aboutsummaryrefslogtreecommitdiff
path: root/crates/hir
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir')
-rw-r--r--crates/hir/src/code_model.rs53
-rw-r--r--crates/hir/src/lib.rs8
-rw-r--r--crates/hir/src/semantics.rs12
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.
690pub enum Access {
691 Shared,
692 Exclusive,
693 Owned,
694}
695
696impl 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)]
706pub struct SelfParam {
707 func: FunctionId,
708}
709
710impl 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
701impl HasVisibility for Function { 724impl 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
33pub use crate::{ 33pub 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
23use crate::{ 23use 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 }