diff options
Diffstat (limited to 'crates/hir')
-rw-r--r-- | crates/hir/src/code_model.rs | 53 | ||||
-rw-r--r-- | crates/hir/src/lib.rs | 8 | ||||
-rw-r--r-- | crates/hir/src/semantics.rs | 12 |
3 files changed, 49 insertions, 24 deletions
diff --git a/crates/hir/src/code_model.rs b/crates/hir/src/code_model.rs index 31d5276b0..3254f316b 100644 --- a/crates/hir/src/code_model.rs +++ b/crates/hir/src/code_model.rs | |||
@@ -666,23 +666,11 @@ impl Function { | |||
666 | db.function_data(self.id).name.clone() | 666 | db.function_data(self.id).name.clone() |
667 | } | 667 | } |
668 | 668 | ||
669 | pub fn has_self_param(self, db: &dyn HirDatabase) -> bool { | 669 | pub fn self_param(self, db: &dyn HirDatabase) -> Option<SelfParam> { |
670 | db.function_data(self.id).has_self_param | 670 | if !db.function_data(self.id).has_self_param { |
671 | } | ||
672 | |||
673 | pub fn mutability_of_self_param(self, db: &dyn HirDatabase) -> Option<Mutability> { | ||
674 | let func_data = db.function_data(self.id); | ||
675 | if !func_data.has_self_param { | ||
676 | return None; | 671 | return None; |
677 | } | 672 | } |
678 | 673 | Some(SelfParam { func: self.id }) | |
679 | func_data.params.first().and_then(|param| { | ||
680 | if let TypeRef::Reference(_, mutability) = param { | ||
681 | Some(*mutability) | ||
682 | } else { | ||
683 | None | ||
684 | } | ||
685 | }) | ||
686 | } | 674 | } |
687 | 675 | ||
688 | pub fn params(self, db: &dyn HirDatabase) -> Vec<TypeRef> { | 676 | pub fn params(self, db: &dyn HirDatabase) -> Vec<TypeRef> { |
@@ -698,6 +686,41 @@ impl Function { | |||
698 | } | 686 | } |
699 | } | 687 | } |
700 | 688 | ||
689 | // Note: logically, this belongs to `hir_ty`, but we are not using it there yet. | ||
690 | pub enum Access { | ||
691 | Shared, | ||
692 | Exclusive, | ||
693 | Owned, | ||
694 | } | ||
695 | |||
696 | impl From<Mutability> for Access { | ||
697 | fn from(mutability: Mutability) -> Access { | ||
698 | match mutability { | ||
699 | Mutability::Shared => Access::Shared, | ||
700 | Mutability::Mut => Access::Exclusive, | ||
701 | } | ||
702 | } | ||
703 | } | ||
704 | |||
705 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
706 | pub struct SelfParam { | ||
707 | func: FunctionId, | ||
708 | } | ||
709 | |||
710 | impl SelfParam { | ||
711 | pub fn access(self, db: &dyn HirDatabase) -> Access { | ||
712 | let func_data = db.function_data(self.func); | ||
713 | func_data | ||
714 | .params | ||
715 | .first() | ||
716 | .map(|param| match *param { | ||
717 | TypeRef::Reference(_, mutability) => mutability.into(), | ||
718 | _ => Access::Owned, | ||
719 | }) | ||
720 | .unwrap_or(Access::Owned) | ||
721 | } | ||
722 | } | ||
723 | |||
701 | impl HasVisibility for Function { | 724 | impl HasVisibility for Function { |
702 | fn visibility(&self, db: &dyn HirDatabase) -> Visibility { | 725 | fn visibility(&self, db: &dyn HirDatabase) -> Visibility { |
703 | let function_data = db.function_data(self.id); | 726 | let function_data = db.function_data(self.id); |
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index fc1c1ccd3..447e60698 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs | |||
@@ -32,10 +32,10 @@ mod has_source; | |||
32 | 32 | ||
33 | pub use crate::{ | 33 | pub use crate::{ |
34 | code_model::{ | 34 | code_model::{ |
35 | Adt, AsAssocItem, AssocItem, AssocItemContainer, AttrDef, Callable, CallableKind, Const, | 35 | Access, Adt, AsAssocItem, AssocItem, AssocItemContainer, AttrDef, Callable, CallableKind, |
36 | Crate, CrateDependency, DefWithBody, Docs, Enum, EnumVariant, Field, FieldSource, Function, | 36 | Const, Crate, CrateDependency, DefWithBody, Docs, Enum, EnumVariant, Field, FieldSource, |
37 | GenericDef, HasAttrs, HasVisibility, ImplDef, Local, MacroDef, Module, ModuleDef, ScopeDef, | 37 | Function, GenericDef, HasAttrs, HasVisibility, ImplDef, Local, MacroDef, Module, ModuleDef, |
38 | Static, Struct, Trait, Type, TypeAlias, TypeParam, Union, VariantDef, Visibility, | 38 | ScopeDef, Static, Struct, Trait, Type, TypeAlias, TypeParam, Union, VariantDef, Visibility, |
39 | }, | 39 | }, |
40 | has_source::HasSource, | 40 | has_source::HasSource, |
41 | semantics::{original_range, PathResolution, SelfKind, Semantics, SemanticsScope}, | 41 | semantics::{original_range, PathResolution, SelfKind, Semantics, SemanticsScope}, |
diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs index 621ebcbe3..cabeaaf98 100644 --- a/crates/hir/src/semantics.rs +++ b/crates/hir/src/semantics.rs | |||
@@ -21,13 +21,13 @@ use syntax::{ | |||
21 | }; | 21 | }; |
22 | 22 | ||
23 | use crate::{ | 23 | use crate::{ |
24 | code_model::Access, | ||
24 | db::HirDatabase, | 25 | db::HirDatabase, |
25 | diagnostics::Diagnostic, | 26 | diagnostics::Diagnostic, |
26 | semantics::source_to_def::{ChildContainer, SourceToDefCache, SourceToDefCtx}, | 27 | semantics::source_to_def::{ChildContainer, SourceToDefCache, SourceToDefCtx}, |
27 | source_analyzer::{resolve_hir_path, SourceAnalyzer}, | 28 | source_analyzer::{resolve_hir_path, SourceAnalyzer}, |
28 | AssocItem, Callable, Crate, Field, Function, HirFileId, ImplDef, InFile, Local, MacroDef, | 29 | AssocItem, Callable, Crate, Field, Function, HirFileId, ImplDef, InFile, Local, MacroDef, |
29 | Module, ModuleDef, Name, Origin, Path, ScopeDef, Trait, Type, TypeAlias, TypeParam, TypeRef, | 30 | Module, ModuleDef, Name, Origin, Path, ScopeDef, Trait, Type, TypeAlias, TypeParam, VariantDef, |
30 | VariantDef, | ||
31 | }; | 31 | }; |
32 | 32 | ||
33 | #[derive(Debug, Clone, PartialEq, Eq)] | 33 | #[derive(Debug, Clone, PartialEq, Eq)] |
@@ -627,9 +627,11 @@ impl<'db> SemanticsImpl<'db> { | |||
627 | } | 627 | } |
628 | 628 | ||
629 | let func = self.resolve_method_call(&method_call_expr).map(Function::from)?; | 629 | let func = self.resolve_method_call(&method_call_expr).map(Function::from)?; |
630 | let is_unsafe = func.has_self_param(self.db) | 630 | let res = match func.self_param(self.db)?.access(self.db) { |
631 | && matches!(func.params(self.db).first(), Some(TypeRef::Reference(..))); | 631 | Access::Shared | Access::Exclusive => true, |
632 | Some(is_unsafe) | 632 | Access::Owned => false, |
633 | }; | ||
634 | Some(res) | ||
633 | }) | 635 | }) |
634 | .unwrap_or(false) | 636 | .unwrap_or(false) |
635 | } | 637 | } |