From b9b4693ce3bf0229ea40f09e6404fad3e7823321 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 19 Aug 2020 15:16:24 +0200 Subject: Add SelfParam to code_model --- crates/hir/src/code_model.rs | 53 +++++++++++++++++++++++++++++++------------- crates/hir/src/lib.rs | 8 +++---- crates/hir/src/semantics.rs | 12 +++++----- 3 files changed, 49 insertions(+), 24 deletions(-) (limited to 'crates/hir') 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 { db.function_data(self.id).name.clone() } - pub fn has_self_param(self, db: &dyn HirDatabase) -> bool { - db.function_data(self.id).has_self_param - } - - pub fn mutability_of_self_param(self, db: &dyn HirDatabase) -> Option { - let func_data = db.function_data(self.id); - if !func_data.has_self_param { + pub fn self_param(self, db: &dyn HirDatabase) -> Option { + if !db.function_data(self.id).has_self_param { return None; } - - func_data.params.first().and_then(|param| { - if let TypeRef::Reference(_, mutability) = param { - Some(*mutability) - } else { - None - } - }) + Some(SelfParam { func: self.id }) } pub fn params(self, db: &dyn HirDatabase) -> Vec { @@ -698,6 +686,41 @@ impl Function { } } +// Note: logically, this belongs to `hir_ty`, but we are not using it there yet. +pub enum Access { + Shared, + Exclusive, + Owned, +} + +impl From for Access { + fn from(mutability: Mutability) -> Access { + match mutability { + Mutability::Shared => Access::Shared, + Mutability::Mut => Access::Exclusive, + } + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub struct SelfParam { + func: FunctionId, +} + +impl SelfParam { + pub fn access(self, db: &dyn HirDatabase) -> Access { + let func_data = db.function_data(self.func); + func_data + .params + .first() + .map(|param| match *param { + TypeRef::Reference(_, mutability) => mutability.into(), + _ => Access::Owned, + }) + .unwrap_or(Access::Owned) + } +} + impl HasVisibility for Function { fn visibility(&self, db: &dyn HirDatabase) -> Visibility { 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; pub use crate::{ code_model::{ - Adt, AsAssocItem, AssocItem, AssocItemContainer, AttrDef, Callable, CallableKind, Const, - Crate, CrateDependency, DefWithBody, Docs, Enum, EnumVariant, Field, FieldSource, Function, - GenericDef, HasAttrs, HasVisibility, ImplDef, Local, MacroDef, Module, ModuleDef, ScopeDef, - Static, Struct, Trait, Type, TypeAlias, TypeParam, Union, VariantDef, Visibility, + Access, Adt, AsAssocItem, AssocItem, AssocItemContainer, AttrDef, Callable, CallableKind, + Const, Crate, CrateDependency, DefWithBody, Docs, Enum, EnumVariant, Field, FieldSource, + Function, GenericDef, HasAttrs, HasVisibility, ImplDef, Local, MacroDef, Module, ModuleDef, + ScopeDef, Static, Struct, Trait, Type, TypeAlias, TypeParam, Union, VariantDef, Visibility, }, has_source::HasSource, 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::{ }; use crate::{ + code_model::Access, db::HirDatabase, diagnostics::Diagnostic, semantics::source_to_def::{ChildContainer, SourceToDefCache, SourceToDefCtx}, source_analyzer::{resolve_hir_path, SourceAnalyzer}, AssocItem, Callable, Crate, Field, Function, HirFileId, ImplDef, InFile, Local, MacroDef, - Module, ModuleDef, Name, Origin, Path, ScopeDef, Trait, Type, TypeAlias, TypeParam, TypeRef, - VariantDef, + Module, ModuleDef, Name, Origin, Path, ScopeDef, Trait, Type, TypeAlias, TypeParam, VariantDef, }; #[derive(Debug, Clone, PartialEq, Eq)] @@ -627,9 +627,11 @@ impl<'db> SemanticsImpl<'db> { } let func = self.resolve_method_call(&method_call_expr).map(Function::from)?; - let is_unsafe = func.has_self_param(self.db) - && matches!(func.params(self.db).first(), Some(TypeRef::Reference(..))); - Some(is_unsafe) + let res = match func.self_param(self.db)?.access(self.db) { + Access::Shared | Access::Exclusive => true, + Access::Owned => false, + }; + Some(res) }) .unwrap_or(false) } -- cgit v1.2.3