diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs index be18c845c643..3fc2eccdd7b8 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs @@ -678,6 +678,10 @@ impl Static { pub fn name(self, db: &dyn HirDatabase) -> Option { 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)] diff --git a/crates/ra_hir_def/src/data.rs b/crates/ra_hir_def/src/data.rs index e7eb2bb1194b..e2130d931fdb 100644 --- a/crates/ra_hir_def/src/data.rs +++ b/crates/ra_hir_def/src/data.rs @@ -251,11 +251,6 @@ impl ConstData { Arc::new(ConstData::new(db, vis_default, node)) } - pub(crate) fn static_data_query(db: &dyn DefDatabase, konst: StaticId) -> Arc { - let node = konst.lookup(db).source(db); - Arc::new(ConstData::new(db, RawVisibility::private(), node)) - } - fn new( db: &dyn DefDatabase, vis_default: RawVisibility, @@ -270,6 +265,32 @@ impl ConstData { } } +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct StaticData { + pub name: Option, + pub type_ref: TypeRef, + pub visibility: RawVisibility, + pub mutable: bool, +} + +impl StaticData { + pub(crate) fn static_data_query(db: &dyn DefDatabase, konst: StaticId) -> Arc { + 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( db: &dyn DefDatabase, expander: &mut Expander, diff --git a/crates/ra_hir_def/src/db.rs b/crates/ra_hir_def/src/db.rs index 5dc7395f5e80..e665ab45d033 100644 --- a/crates/ra_hir_def/src/db.rs +++ b/crates/ra_hir_def/src/db.rs @@ -10,7 +10,7 @@ use crate::{ adt::{EnumData, StructData}, attr::Attrs, body::{scope::ExprScopes, Body, BodySourceMap}, - data::{ConstData, FunctionData, ImplData, TraitData, TypeAliasData}, + data::{ConstData, FunctionData, ImplData, StaticData, TraitData, TypeAliasData}, docs::Documentation, generics::GenericParams, lang_item::{LangItemTarget, LangItems}, @@ -77,8 +77,8 @@ pub trait DefDatabase: InternDatabase + AstDatabase + Upcast { #[salsa::invoke(ConstData::const_data_query)] fn const_data(&self, konst: ConstId) -> Arc; - #[salsa::invoke(ConstData::static_data_query)] - fn static_data(&self, konst: StaticId) -> Arc; + #[salsa::invoke(StaticData::static_data_query)] + fn static_data(&self, konst: StaticId) -> Arc; #[salsa::invoke(Body::body_with_source_map_query)] fn body_with_source_map(&self, def: DefWithBodyId) -> (Arc, Arc); diff --git a/crates/ra_hir_ty/src/infer.rs b/crates/ra_hir_ty/src/infer.rs index a21ad8d86416..fb7c6cd8c14c 100644 --- a/crates/ra_hir_ty/src/infer.rs +++ b/crates/ra_hir_ty/src/infer.rs @@ -22,7 +22,7 @@ use rustc_hash::FxHashMap; use hir_def::{ body::Body, - data::{ConstData, FunctionData}, + data::{ConstData, FunctionData, StaticData}, expr::{BindingAnnotation, ExprId, PatId}, lang_item::LangItemTarget, path::{path, Path}, @@ -71,7 +71,7 @@ pub(crate) fn infer_query(db: &dyn HirDatabase, def: DefWithBodyId) -> Arc ctx.collect_const(&db.const_data(c)), 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(); @@ -485,6 +485,10 @@ impl<'a> InferenceContext<'a> { 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) { let body = Arc::clone(&self.body); // avoid borrow checker problem let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver) diff --git a/crates/ra_ide/src/snapshots/highlight_strings.html b/crates/ra_ide/src/snapshots/highlight_strings.html index de06daf72b08..752b487e82fa 100644 --- a/crates/ra_ide/src/snapshots/highlight_strings.html +++ b/crates/ra_ide/src/snapshots/highlight_strings.html @@ -27,13 +27,13 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd .keyword.unsafe { color: #BC8383; font-weight: bold; } .control { font-style: italic; } -
macro_rules! println {
+
macro_rules! println {
     ($($arg:tt)*) => ({
         $crate::io::_print($crate::format_args_nl!($($arg)*));
     })
 }
 #[rustc_builtin_macro]
-macro_rules! format_args_nl {
+macro_rules! format_args_nl {
     ($fmt:expr) => {{ /* compiler built-in */ }};
     ($fmt:expr, $($args:tt)*) => {{ /* compiler built-in */ }};
 }
diff --git a/crates/ra_ide/src/snapshots/highlighting.html b/crates/ra_ide/src/snapshots/highlighting.html
index 4b12fe8238cf..4c27aade4025 100644
--- a/crates/ra_ide/src/snapshots/highlighting.html
+++ b/crates/ra_ide/src/snapshots/highlighting.html
@@ -33,11 +33,13 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
     pub y: i32,
 }
 
+static mut STATIC_MUT: i32 = 0;
+
 fn foo<'a, T>() -> T {
     foo::<'a, i32>()
 }
 
-macro_rules! def_fn {
+macro_rules! def_fn {
     ($($tt:tt)*) => {$($tt)*}
 }
 
@@ -56,7 +58,10 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
         let x = 92;
         vec.push(Foo { x, y: 1 });
     }
-    unsafe { vec.set_len(0); }
+    unsafe {
+        vec.set_len(0);
+        STATIC_MUT = 1;
+    }
 
     let mut x = 42;
     let y = &mut x;
diff --git a/crates/ra_ide/src/syntax_highlighting.rs b/crates/ra_ide/src/syntax_highlighting.rs
index 6658c7bb270e..d53a39f57b52 100644
--- a/crates/ra_ide/src/syntax_highlighting.rs
+++ b/crates/ra_ide/src/syntax_highlighting.rs
@@ -167,6 +167,19 @@ pub(crate) fn highlight(
                         binding_hash: None,
                     });
                 }
+                if let Some(name) = mc.is_macro_rules() {
+                    if let Some((highlight, binding_hash)) = highlight_element(
+                        &sema,
+                        &mut bindings_shadow_count,
+                        name.syntax().clone().into(),
+                    ) {
+                        stack.add(HighlightedRange {
+                            range: name.syntax().text_range(),
+                            highlight,
+                            binding_hash,
+                        });
+                    }
+                }
                 continue;
             }
             WalkEvent::Leave(Some(mc)) => {
@@ -431,10 +444,16 @@ fn highlight_name(db: &RootDatabase, def: Definition) -> Highlight {
             hir::ModuleDef::Adt(hir::Adt::Union(_)) => HighlightTag::Union,
             hir::ModuleDef::EnumVariant(_) => HighlightTag::EnumVariant,
             hir::ModuleDef::Const(_) => HighlightTag::Constant,
-            hir::ModuleDef::Static(_) => HighlightTag::Static,
             hir::ModuleDef::Trait(_) => HighlightTag::Trait,
             hir::ModuleDef::TypeAlias(_) => HighlightTag::TypeAlias,
             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::TypeParam(_) => HighlightTag::TypeParam,
diff --git a/crates/ra_ide/src/syntax_highlighting/tests.rs b/crates/ra_ide/src/syntax_highlighting/tests.rs
index d2926ba78029..13894869c8bf 100644
--- a/crates/ra_ide/src/syntax_highlighting/tests.rs
+++ b/crates/ra_ide/src/syntax_highlighting/tests.rs
@@ -17,6 +17,8 @@ struct Foo {
     pub y: i32,
 }
 
+static mut STATIC_MUT: i32 = 0;
+
 fn foo<'a, T>() -> T {
     foo::<'a, i32>()
 }
@@ -40,7 +42,10 @@ fn main() {
         let x = 92;
         vec.push(Foo { x, y: 1 });
     }
-    unsafe { vec.set_len(0); }
+    unsafe {
+        vec.set_len(0);
+        STATIC_MUT = 1;
+    }
 
     let mut x = 42;
     let y = &mut x;
diff --git a/crates/ra_toolchain/src/lib.rs b/crates/ra_toolchain/src/lib.rs
index 3c307a0eace4..3d2865e09c8f 100644
--- a/crates/ra_toolchain/src/lib.rs
+++ b/crates/ra_toolchain/src/lib.rs
@@ -53,10 +53,9 @@ fn lookup_in_path(exec: &str) -> bool {
     let paths = env::var_os("PATH").unwrap_or_default();
     let mut candidates = env::split_paths(&paths).flat_map(|path| {
         let candidate = path.join(&exec);
-        let with_exe = if env::consts::EXE_EXTENSION == "" {
-            None
-        } else {
-            Some(candidate.with_extension(env::consts::EXE_EXTENSION))
+        let with_exe = match env::consts::EXE_EXTENSION {
+            "" => None,
+            it => Some(candidate.with_extension(it)),
         };
         iter::once(candidate).chain(with_exe)
     });
diff --git a/crates/rust-analyzer/src/main_loop.rs b/crates/rust-analyzer/src/main_loop.rs
index fa72a9cc64d2..3f12dd71830c 100644
--- a/crates/rust-analyzer/src/main_loop.rs
+++ b/crates/rust-analyzer/src/main_loop.rs
@@ -174,7 +174,6 @@ pub fn main_loop(ws_roots: Vec, config: Config, connection: Connection)
     };
 
     loop_state.roots_total = world_state.vfs.read().n_roots();
-    loop_state.roots_scanned = 0;
 
     let pool = ThreadPool::default();
     let (task_sender, task_receiver) = unbounded::();
@@ -401,10 +400,12 @@ fn loop_turn(
     }
 
     let max_in_flight_libs = pool.max_count().saturating_sub(2).max(1);
-    while loop_state.in_flight_libraries < max_in_flight_libs
-        && !loop_state.pending_libraries.is_empty()
-    {
-        let (root, files) = loop_state.pending_libraries.pop().unwrap();
+    while loop_state.in_flight_libraries < max_in_flight_libs {
+        let (root, files) = match loop_state.pending_libraries.pop() {
+            Some(it) => it,
+            None => break,
+        };
+
         loop_state.in_flight_libraries += 1;
         let sender = libdata_sender.clone();
         pool.execute(move || {
diff --git a/crates/rust-analyzer/src/world.rs b/crates/rust-analyzer/src/world.rs
index 16020648df68..6333c15b2bba 100644
--- a/crates/rust-analyzer/src/world.rs
+++ b/crates/rust-analyzer/src/world.rs
@@ -137,15 +137,6 @@ impl WorldState {
             opts
         };
 
-        // Create crate graph from all the workspaces
-        let mut crate_graph = CrateGraph::default();
-        let mut load = |path: &std::path::Path| {
-            // Some path from metadata will be non canonicalized, e.g. /foo/../bar/lib.rs
-            let path = path.canonicalize().ok()?;
-            let vfs_file = vfs.load(&path);
-            vfs_file.map(|f| FileId(f.0))
-        };
-
         let proc_macro_client = match &config.proc_macro_srv {
             None => ProcMacroClient::dummy(),
             Some((path, args)) => match ProcMacroClient::extern_process(path.into(), args) {
@@ -161,19 +152,22 @@ impl WorldState {
             },
         };
 
-        workspaces
-            .iter()
-            .map(|ws| {
-                ws.to_crate_graph(
-                    &default_cfg_options,
-                    &extern_source_roots,
-                    &proc_macro_client,
-                    &mut load,
-                )
-            })
-            .for_each(|graph| {
-                crate_graph.extend(graph);
-            });
+        // Create crate graph from all the workspaces
+        let mut crate_graph = CrateGraph::default();
+        let mut load = |path: &Path| {
+            // Some path from metadata will be non canonicalized, e.g. /foo/../bar/lib.rs
+            let path = path.canonicalize().ok()?;
+            let vfs_file = vfs.load(&path);
+            vfs_file.map(|f| FileId(f.0))
+        };
+        for ws in workspaces.iter() {
+            crate_graph.extend(ws.to_crate_graph(
+                &default_cfg_options,
+                &extern_source_roots,
+                &proc_macro_client,
+                &mut load,
+            ));
+        }
         change.set_crate_graph(crate_graph);
 
         let flycheck = config.check.as_ref().and_then(|c| create_flycheck(&workspaces, c));