Highlight mutable statics as mutable

This commit is contained in:
Matthew Jasper 2020-05-10 16:08:28 +01:00
parent 4578154b60
commit 11c0a5bb60
7 changed files with 56 additions and 13 deletions

View file

@ -678,6 +678,10 @@ impl Static {
pub fn name(self, db: &dyn HirDatabase) -> Option<Name> { pub fn name(self, db: &dyn HirDatabase) -> Option<Name> {
db.static_data(self.id).name.clone() db.static_data(self.id).name.clone()
} }
pub fn is_mut(self, db: &dyn HirDatabase) -> bool {
db.static_data(self.id).mutable
}
} }
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]

View file

@ -251,11 +251,6 @@ impl ConstData {
Arc::new(ConstData::new(db, vis_default, node)) Arc::new(ConstData::new(db, vis_default, node))
} }
pub(crate) fn static_data_query(db: &dyn DefDatabase, konst: StaticId) -> Arc<ConstData> {
let node = konst.lookup(db).source(db);
Arc::new(ConstData::new(db, RawVisibility::private(), node))
}
fn new<N: NameOwner + TypeAscriptionOwner + VisibilityOwner>( fn new<N: NameOwner + TypeAscriptionOwner + VisibilityOwner>(
db: &dyn DefDatabase, db: &dyn DefDatabase,
vis_default: RawVisibility, vis_default: RawVisibility,
@ -270,6 +265,32 @@ impl ConstData {
} }
} }
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct StaticData {
pub name: Option<Name>,
pub type_ref: TypeRef,
pub visibility: RawVisibility,
pub mutable: bool,
}
impl StaticData {
pub(crate) fn static_data_query(db: &dyn DefDatabase, konst: StaticId) -> Arc<StaticData> {
let node = konst.lookup(db).source(db);
let ctx = LowerCtx::new(db, node.file_id);
let name = node.value.name().map(|n| n.as_name());
let type_ref = TypeRef::from_ast_opt(&ctx, node.value.ascribed_type());
let mutable = node.value.mut_token().is_some();
let visibility = RawVisibility::from_ast_with_default(
db,
RawVisibility::private(),
node.map(|n| n.visibility()),
);
Arc::new(StaticData { name, type_ref, visibility, mutable })
}
}
fn collect_items_in_macros( fn collect_items_in_macros(
db: &dyn DefDatabase, db: &dyn DefDatabase,
expander: &mut Expander, expander: &mut Expander,

View file

@ -10,7 +10,7 @@ use crate::{
adt::{EnumData, StructData}, adt::{EnumData, StructData},
attr::Attrs, attr::Attrs,
body::{scope::ExprScopes, Body, BodySourceMap}, body::{scope::ExprScopes, Body, BodySourceMap},
data::{ConstData, FunctionData, ImplData, TraitData, TypeAliasData}, data::{ConstData, FunctionData, ImplData, StaticData, TraitData, TypeAliasData},
docs::Documentation, docs::Documentation,
generics::GenericParams, generics::GenericParams,
lang_item::{LangItemTarget, LangItems}, lang_item::{LangItemTarget, LangItems},
@ -77,8 +77,8 @@ pub trait DefDatabase: InternDatabase + AstDatabase + Upcast<dyn AstDatabase> {
#[salsa::invoke(ConstData::const_data_query)] #[salsa::invoke(ConstData::const_data_query)]
fn const_data(&self, konst: ConstId) -> Arc<ConstData>; fn const_data(&self, konst: ConstId) -> Arc<ConstData>;
#[salsa::invoke(ConstData::static_data_query)] #[salsa::invoke(StaticData::static_data_query)]
fn static_data(&self, konst: StaticId) -> Arc<ConstData>; fn static_data(&self, konst: StaticId) -> Arc<StaticData>;
#[salsa::invoke(Body::body_with_source_map_query)] #[salsa::invoke(Body::body_with_source_map_query)]
fn body_with_source_map(&self, def: DefWithBodyId) -> (Arc<Body>, Arc<BodySourceMap>); fn body_with_source_map(&self, def: DefWithBodyId) -> (Arc<Body>, Arc<BodySourceMap>);

View file

@ -22,7 +22,7 @@ use rustc_hash::FxHashMap;
use hir_def::{ use hir_def::{
body::Body, body::Body,
data::{ConstData, FunctionData}, data::{ConstData, FunctionData, StaticData},
expr::{BindingAnnotation, ExprId, PatId}, expr::{BindingAnnotation, ExprId, PatId},
lang_item::LangItemTarget, lang_item::LangItemTarget,
path::{path, Path}, path::{path, Path},
@ -71,7 +71,7 @@ pub(crate) fn infer_query(db: &dyn HirDatabase, def: DefWithBodyId) -> Arc<Infer
match def { match def {
DefWithBodyId::ConstId(c) => ctx.collect_const(&db.const_data(c)), DefWithBodyId::ConstId(c) => ctx.collect_const(&db.const_data(c)),
DefWithBodyId::FunctionId(f) => ctx.collect_fn(&db.function_data(f)), DefWithBodyId::FunctionId(f) => ctx.collect_fn(&db.function_data(f)),
DefWithBodyId::StaticId(s) => ctx.collect_const(&db.static_data(s)), DefWithBodyId::StaticId(s) => ctx.collect_static(&db.static_data(s)),
} }
ctx.infer_body(); ctx.infer_body();
@ -485,6 +485,10 @@ impl<'a> InferenceContext<'a> {
self.return_ty = self.make_ty(&data.type_ref); self.return_ty = self.make_ty(&data.type_ref);
} }
fn collect_static(&mut self, data: &StaticData) {
self.return_ty = self.make_ty(&data.type_ref);
}
fn collect_fn(&mut self, data: &FunctionData) { fn collect_fn(&mut self, data: &FunctionData) {
let body = Arc::clone(&self.body); // avoid borrow checker problem let body = Arc::clone(&self.body); // avoid borrow checker problem
let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver) let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver)

View file

@ -56,7 +56,10 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
<span class="keyword">let</span> <span class="variable declaration">x</span> = <span class="numeric_literal">92</span>; <span class="keyword">let</span> <span class="variable declaration">x</span> = <span class="numeric_literal">92</span>;
<span class="variable mutable">vec</span>.<span class="unresolved_reference">push</span>(<span class="struct">Foo</span> { <span class="field">x</span>, <span class="field">y</span>: <span class="numeric_literal">1</span> }); <span class="variable mutable">vec</span>.<span class="unresolved_reference">push</span>(<span class="struct">Foo</span> { <span class="field">x</span>, <span class="field">y</span>: <span class="numeric_literal">1</span> });
} }
<span class="keyword unsafe">unsafe</span> { <span class="variable mutable">vec</span>.<span class="unresolved_reference">set_len</span>(<span class="numeric_literal">0</span>); } <span class="keyword unsafe">unsafe</span> {
<span class="variable mutable">vec</span>.<span class="unresolved_reference">set_len</span>(<span class="numeric_literal">0</span>);
<span class="static mutable">STATIC_MUT</span> = <span class="numeric_literal">1</span>;
}
<span class="keyword">let</span> <span class="keyword">mut</span> <span class="variable declaration mutable">x</span> = <span class="numeric_literal">42</span>; <span class="keyword">let</span> <span class="keyword">mut</span> <span class="variable declaration mutable">x</span> = <span class="numeric_literal">42</span>;
<span class="keyword">let</span> <span class="variable declaration mutable">y</span> = &<span class="keyword">mut</span> <span class="variable mutable">x</span>; <span class="keyword">let</span> <span class="variable declaration mutable">y</span> = &<span class="keyword">mut</span> <span class="variable mutable">x</span>;

View file

@ -431,10 +431,16 @@ fn highlight_name(db: &RootDatabase, def: Definition) -> Highlight {
hir::ModuleDef::Adt(hir::Adt::Union(_)) => HighlightTag::Union, hir::ModuleDef::Adt(hir::Adt::Union(_)) => HighlightTag::Union,
hir::ModuleDef::EnumVariant(_) => HighlightTag::EnumVariant, hir::ModuleDef::EnumVariant(_) => HighlightTag::EnumVariant,
hir::ModuleDef::Const(_) => HighlightTag::Constant, hir::ModuleDef::Const(_) => HighlightTag::Constant,
hir::ModuleDef::Static(_) => HighlightTag::Static,
hir::ModuleDef::Trait(_) => HighlightTag::Trait, hir::ModuleDef::Trait(_) => HighlightTag::Trait,
hir::ModuleDef::TypeAlias(_) => HighlightTag::TypeAlias, hir::ModuleDef::TypeAlias(_) => HighlightTag::TypeAlias,
hir::ModuleDef::BuiltinType(_) => HighlightTag::BuiltinType, hir::ModuleDef::BuiltinType(_) => HighlightTag::BuiltinType,
hir::ModuleDef::Static(s) => {
let mut h = Highlight::new(HighlightTag::Static);
if s.is_mut(db) {
h |= HighlightModifier::Mutable;
}
return h;
}
}, },
Definition::SelfType(_) => HighlightTag::SelfType, Definition::SelfType(_) => HighlightTag::SelfType,
Definition::TypeParam(_) => HighlightTag::TypeParam, Definition::TypeParam(_) => HighlightTag::TypeParam,

View file

@ -17,6 +17,8 @@ struct Foo {
pub y: i32, pub y: i32,
} }
static mut STATIC_MUT: i32 = 0;
fn foo<'a, T>() -> T { fn foo<'a, T>() -> T {
foo::<'a, i32>() foo::<'a, i32>()
} }
@ -40,7 +42,10 @@ fn main() {
let x = 92; let x = 92;
vec.push(Foo { x, y: 1 }); vec.push(Foo { x, y: 1 });
} }
unsafe { vec.set_len(0); } unsafe {
vec.set_len(0);
STATIC_MUT = 1;
}
let mut x = 42; let mut x = 42;
let y = &mut x; let y = &mut x;