Mark mutating functions with mutable modifier, and owning functions with consuming.

This commit is contained in:
Paul Daniel Faria 2020-07-30 11:07:13 -04:00
parent 7009d5ee2b
commit a044ff0138
5 changed files with 70 additions and 15 deletions

View File

@ -670,6 +670,21 @@ impl Function {
db.function_data(self.id).has_self_param
}
pub fn mutability_of_self_param(self, db: &dyn HirDatabase) -> Option<Mutability> {
let func_data = db.function_data(self.id);
if !func_data.has_self_param {
return None;
}
func_data.params.first().and_then(|param| {
if let TypeRef::Reference(_, mutability) = param {
Some(*mutability)
} else {
None
}
})
}
pub fn params(self, db: &dyn HirDatabase) -> Vec<TypeRef> {
db.function_data(self.id).params.clone()
}

View File

@ -267,7 +267,7 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
self.imp.assert_contains_node(node)
}
pub fn is_unsafe_method_call(&self, method_call_expr: ast::MethodCallExpr) -> bool {
pub fn is_unsafe_method_call(&self, method_call_expr: &ast::MethodCallExpr) -> bool {
self.imp.is_unsafe_method_call(method_call_expr)
}
@ -571,7 +571,7 @@ impl<'db> SemanticsImpl<'db> {
InFile::new(file_id, node)
}
pub fn is_unsafe_method_call(&self, method_call_expr: ast::MethodCallExpr) -> bool {
pub fn is_unsafe_method_call(&self, method_call_expr: &ast::MethodCallExpr) -> bool {
method_call_expr
.expr()
.and_then(|expr| {

View File

@ -4,7 +4,7 @@ mod injection;
#[cfg(test)]
mod tests;
use hir::{Name, Semantics, VariantDef};
use hir::{Mutability, Name, Semantics, VariantDef};
use ide_db::{
defs::{classify_name, classify_name_ref, Definition, NameClass, NameRefClass},
RootDatabase,
@ -729,13 +729,23 @@ fn highlight_name(
let is_unsafe = name_ref
.and_then(|name_ref| name_ref.syntax().parent())
.and_then(ast::MethodCallExpr::cast)
.map(|method_call_expr| sema.is_unsafe_method_call(method_call_expr))
.map(|method_call_expr| sema.is_unsafe_method_call(&method_call_expr))
.unwrap_or(false);
if is_unsafe {
h |= HighlightModifier::Unsafe;
}
}
return h;
return if func.has_self_param(db) {
match func.mutability_of_self_param(db) {
Some(mutability) => match mutability {
Mutability::Mut => h | HighlightModifier::Mutable,
Mutability::Shared => h,
},
None => h | HighlightModifier::Consuming,
}
} else {
h
};
}
hir::ModuleDef::Adt(hir::Adt::Struct(_)) => HighlightTag::Struct,
hir::ModuleDef::Adt(hir::Adt::Enum(_)) => HighlightTag::Enum,
@ -808,14 +818,26 @@ fn highlight_name_ref_by_syntax(name: ast::NameRef, sema: &Semantics<RootDatabas
match parent.kind() {
METHOD_CALL_EXPR => {
let mut h = Highlight::new(HighlightTag::Function);
let is_unsafe = ast::MethodCallExpr::cast(parent)
.map(|method_call_expr| sema.is_unsafe_method_call(method_call_expr))
.unwrap_or(false);
if is_unsafe {
h |= HighlightModifier::Unsafe;
}
ast::MethodCallExpr::cast(parent)
.and_then(|method_call_expr| {
if sema.is_unsafe_method_call(&method_call_expr) {
h |= HighlightModifier::Unsafe;
}
h
let func = sema.resolve_method_call(&method_call_expr)?;
if !func.has_self_param(sema.db) {
return Some(h);
}
Some(match func.mutability_of_self_param(sema.db) {
Some(mutability) => match mutability {
Mutability::Mut => h | HighlightModifier::Mutable,
Mutability::Shared => h,
},
None => h | HighlightModifier::Consuming,
})
})
.unwrap_or_else(|| h)
}
FIELD_EXPR => {
let h = HighlightTag::Field;

View File

@ -36,6 +36,10 @@ impl Foo {
fn qux(&mut self) {
self.x = 0;
}
fn quop(&self) -> i32 {
self.x
}
}
static mut STATIC_MUT: i32 = 0;
@ -87,6 +91,11 @@ fn main() {
let Foo { x: z, y } = Foo { x: z, y };
y;
let mut foo = Foo { x, y: x };
foo.quop();
foo.qux();
foo.baz();
}
enum Option<T> {

View File

@ -55,13 +55,17 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
<span class="punctuation">}</span>
<span class="keyword">impl</span> <span class="struct">Foo</span> <span class="punctuation">{</span>
<span class="keyword">fn</span> <span class="function declaration">baz</span><span class="punctuation">(</span><span class="keyword">mut</span> <span class="self_keyword mutable">self</span><span class="punctuation">)</span> <span class="operator">-&gt;</span> <span class="builtin_type">i32</span> <span class="punctuation">{</span>
<span class="keyword">fn</span> <span class="function declaration consuming">baz</span><span class="punctuation">(</span><span class="keyword">mut</span> <span class="self_keyword mutable">self</span><span class="punctuation">)</span> <span class="operator">-&gt;</span> <span class="builtin_type">i32</span> <span class="punctuation">{</span>
<span class="self_keyword">self</span><span class="punctuation">.</span><span class="field">x</span>
<span class="punctuation">}</span>
<span class="keyword">fn</span> <span class="function declaration">qux</span><span class="punctuation">(</span><span class="operator">&</span><span class="keyword">mut</span> <span class="self_keyword mutable">self</span><span class="punctuation">)</span> <span class="punctuation">{</span>
<span class="keyword">fn</span> <span class="function declaration mutable">qux</span><span class="punctuation">(</span><span class="operator">&</span><span class="keyword">mut</span> <span class="self_keyword mutable">self</span><span class="punctuation">)</span> <span class="punctuation">{</span>
<span class="self_keyword mutable">self</span><span class="punctuation">.</span><span class="field">x</span> <span class="operator">=</span> <span class="numeric_literal">0</span><span class="punctuation">;</span>
<span class="punctuation">}</span>
<span class="keyword">fn</span> <span class="function declaration">quop</span><span class="punctuation">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="punctuation">)</span> <span class="operator">-&gt;</span> <span class="builtin_type">i32</span> <span class="punctuation">{</span>
<span class="self_keyword">self</span><span class="punctuation">.</span><span class="field">x</span>
<span class="punctuation">}</span>
<span class="punctuation">}</span>
<span class="keyword">static</span> <span class="keyword">mut</span> <span class="static declaration mutable unsafe">STATIC_MUT</span><span class="punctuation">:</span> <span class="builtin_type">i32</span> <span class="operator">=</span> <span class="numeric_literal">0</span><span class="punctuation">;</span>
@ -113,6 +117,11 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
<span class="keyword">let</span> <span class="struct">Foo</span> <span class="punctuation">{</span> <span class="field">x</span><span class="punctuation">:</span> <span class="variable declaration">z</span><span class="punctuation">,</span> <span class="field">y</span> <span class="punctuation">}</span> <span class="operator">=</span> <span class="struct">Foo</span> <span class="punctuation">{</span> <span class="field">x</span><span class="punctuation">:</span> <span class="variable">z</span><span class="punctuation">,</span> <span class="field">y</span> <span class="punctuation">}</span><span class="punctuation">;</span>
<span class="variable">y</span><span class="punctuation">;</span>
<span class="keyword">let</span> <span class="keyword">mut</span> <span class="variable declaration mutable">foo</span> <span class="operator">=</span> <span class="struct">Foo</span> <span class="punctuation">{</span> <span class="field">x</span><span class="punctuation">,</span> <span class="field">y</span><span class="punctuation">:</span> <span class="variable mutable">x</span> <span class="punctuation">}</span><span class="punctuation">;</span>
<span class="variable mutable">foo</span><span class="punctuation">.</span><span class="function">quop</span><span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">;</span>
<span class="variable mutable">foo</span><span class="punctuation">.</span><span class="function mutable">qux</span><span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">;</span>
<span class="variable mutable">foo</span><span class="punctuation">.</span><span class="function consuming">baz</span><span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">;</span>
<span class="punctuation">}</span>
<span class="keyword">enum</span> <span class="enum declaration">Option</span><span class="punctuation">&lt;</span><span class="type_param declaration">T</span><span class="punctuation">&gt;</span> <span class="punctuation">{</span>
@ -122,7 +131,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
<span class="keyword">use</span> <span class="enum">Option</span><span class="operator">::</span><span class="punctuation">*</span><span class="punctuation">;</span>
<span class="keyword">impl</span><span class="punctuation">&lt;</span><span class="type_param declaration">T</span><span class="punctuation">&gt;</span> <span class="enum">Option</span><span class="punctuation">&lt;</span><span class="type_param">T</span><span class="punctuation">&gt;</span> <span class="punctuation">{</span>
<span class="keyword">fn</span> <span class="function declaration">and</span><span class="punctuation">&lt;</span><span class="type_param declaration">U</span><span class="punctuation">&gt;</span><span class="punctuation">(</span><span class="self_keyword">self</span><span class="punctuation">,</span> <span class="value_param declaration">other</span><span class="punctuation">:</span> <span class="enum">Option</span><span class="punctuation">&lt;</span><span class="type_param">U</span><span class="punctuation">&gt;</span><span class="punctuation">)</span> <span class="operator">-&gt;</span> <span class="enum">Option</span><span class="punctuation">&lt;</span><span class="punctuation">(</span><span class="type_param">T</span><span class="punctuation">,</span> <span class="type_param">U</span><span class="punctuation">)</span><span class="punctuation">&gt;</span> <span class="punctuation">{</span>
<span class="keyword">fn</span> <span class="function declaration consuming">and</span><span class="punctuation">&lt;</span><span class="type_param declaration">U</span><span class="punctuation">&gt;</span><span class="punctuation">(</span><span class="self_keyword">self</span><span class="punctuation">,</span> <span class="value_param declaration">other</span><span class="punctuation">:</span> <span class="enum">Option</span><span class="punctuation">&lt;</span><span class="type_param">U</span><span class="punctuation">&gt;</span><span class="punctuation">)</span> <span class="operator">-&gt;</span> <span class="enum">Option</span><span class="punctuation">&lt;</span><span class="punctuation">(</span><span class="type_param">T</span><span class="punctuation">,</span> <span class="type_param">U</span><span class="punctuation">)</span><span class="punctuation">&gt;</span> <span class="punctuation">{</span>
<span class="keyword control">match</span> <span class="value_param">other</span> <span class="punctuation">{</span>
<span class="enum_variant">None</span> <span class="operator">=&gt;</span> <span class="macro">unimplemented!</span><span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">,</span>
<span class="variable declaration">Nope</span> <span class="operator">=&gt;</span> <span class="variable">Nope</span><span class="punctuation">,</span>