Repository: rust-analyzer/rust-analyzer
Pull request #1969 (2019-10-08 11:52:20)

restore coloring of attributes


Patch:
diff --git a/crates/ra_batch/src/lib.rs b/crates/ra_batch/src/lib.rs
index a5fc2a23e1..602beb4394 100644
--- a/crates/ra_batch/src/lib.rs
+++ b/crates/ra_batch/src/lib.rs
@@ -43,8 +43,12 @@ pub fn load_cargo(root: &Path) -> Result<(AnalysisHost, FxHashMap<SourceRootId,
     );
 
     // FIXME: cfg options?
-    let default_cfg_options =
-        get_rustc_cfg_options().atom("test".into()).atom("debug_assertion".into());
+    let default_cfg_options = {
+        let mut opts = get_rustc_cfg_options();
+        opts.insert_atom("test".into());
+        opts.insert_atom("debug_assertion".into());
+        opts
+    };
 
     let (crate_graph, _crate_names) =
         ws.to_crate_graph(&default_cfg_options, &mut |path: &Path| {
diff --git a/crates/ra_cfg/src/lib.rs b/crates/ra_cfg/src/lib.rs
index e1c92fbba3..1bee3eb995 100644
--- a/crates/ra_cfg/src/lib.rs
+++ b/crates/ra_cfg/src/lib.rs
@@ -36,26 +36,20 @@ impl CfgOptions {
         self.check(&parse_cfg(attr))
     }
 
-    pub fn atom(mut self, name: SmolStr) -> CfgOptions {
-        self.atoms.insert(name);
-        self
+    pub fn insert_atom(&mut self, key: SmolStr) {
+        self.atoms.insert(key);
     }
 
-    pub fn key_value(mut self, key: SmolStr, value: SmolStr) -> CfgOptions {
-        self.key_values.insert((key, value));
-        self
+    pub fn remove_atom(&mut self, name: &str) {
+        self.atoms.remove(name);
     }
 
-    /// Shortcut to set features
-    pub fn features(mut self, iter: impl IntoIterator<Item = SmolStr>) -> CfgOptions {
-        for feat in iter {
-            self = self.key_value("feature".into(), feat);
-        }
-        self
+    pub fn insert_key_value(&mut self, key: SmolStr, value: SmolStr) {
+        self.key_values.insert((key, value));
     }
 
-    pub fn remove_atom(mut self, name: &SmolStr) -> CfgOptions {
-        self.atoms.remove(name);
-        self
+    /// Shortcut to set features
+    pub fn insert_features(&mut self, iter: impl IntoIterator<Item = SmolStr>) {
+        iter.into_iter().for_each(|feat| self.insert_key_value("feature".into(), feat));
     }
 }
diff --git a/crates/ra_hir/src/mock.rs b/crates/ra_hir/src/mock.rs
index f750986b8b..8274249835 100644
--- a/crates/ra_hir/src/mock.rs
+++ b/crates/ra_hir/src/mock.rs
@@ -278,7 +278,10 @@ macro_rules! crate_graph {
             $crate_path:literal,
             $($edition:literal,)?
             [$($dep:literal),*]
-            $(,$cfg:expr)?
+            $(, cfg = {
+                $($key:literal $(= $value:literal)?),*
+                $(,)?
+            })?
         ),
     )*) => {{
         let mut res = $crate::mock::CrateGraphFixture::default();
@@ -286,7 +289,19 @@ macro_rules! crate_graph {
             #[allow(unused_mut, unused_assignments)]
             let mut edition = ra_db::Edition::Edition2018;
             $(edition = ra_db::Edition::from_string($edition);)?
-            let cfg_options = { ::ra_cfg::CfgOptions::default() $(; $cfg)? };
+            let cfg_options = {
+                #[allow(unused_mut)]
+                let mut cfg = ::ra_cfg::CfgOptions::default();
+                $(
+                    $(
+                        if 0 == 0 $(+ { drop($value); 1})? {
+                            cfg.insert_atom($key.into());
+                        }
+                        $(cfg.insert_key_value($key.into(), $value.into());)?
+                    )*
+                )?
+                cfg
+            };
             res.0.push((
                 $crate_name.to_string(),
                 ($crate_path.to_string(), edition, cfg_options, vec![$($dep.to_string()),*])
diff --git a/crates/ra_ide_api/src/lib.rs b/crates/ra_ide_api/src/lib.rs
index 24f1b91f68..2d92fe1c50 100644
--- a/crates/ra_ide_api/src/lib.rs
+++ b/crates/ra_ide_api/src/lib.rs
@@ -325,7 +325,8 @@ impl Analysis {
         let file_id = FileId(0);
         // FIXME: cfg options
         // Default to enable test for single file.
-        let cfg_options = CfgOptions::default().atom("test".into());
+        let mut cfg_options = CfgOptions::default();
+        cfg_options.insert_atom("test".into());
         crate_graph.add_crate_root(file_id, Edition::Edition2018, cfg_options);
         change.add_file(source_root, file_id, "main.rs".into(), Arc::new(text));
         change.set_crate_graph(crate_graph);
diff --git a/crates/ra_ide_api/src/snapshots/highlighting.html b/crates/ra_ide_api/src/snapshots/highlighting.html
index ae30ebba38..b39c4d3717 100644
--- a/crates/ra_ide_api/src/snapshots/highlighting.html
+++ b/crates/ra_ide_api/src/snapshots/highlighting.html
@@ -19,7 +19,7 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
 .keyword\.unsafe   { color: #DFAF8F; }
 .keyword\.control  { color: #F0DFAF; font-weight: bold; }
 </style>
-<pre><code><span class="attribute">#</span><span class="attribute">[</span><span class="attribute text">derive</span><span class="attribute">(</span><span class="attribute">Clone</span><span class="attribute">,</span><span class="attribute"> </span><span class="attribute">Debug</span><span class="attribute">)</span><span class="attribute">]</span>
+<pre><code><span class="attribute">#</span><span class="attribute">[</span><span class="attribute">derive</span><span class="attribute">(</span><span class="attribute">Clone</span><span class="attribute">,</span><span class="attribute"> </span><span class="attribute">Debug</span><span class="attribute">)</span><span class="attribute">]</span>
 <span class="keyword">struct</span> <span class="type">Foo</span> {
     <span class="keyword">pub</span> <span class="field">x</span>: <span class="type">i32</span>,
     <span class="keyword">pub</span> <span class="field">y</span>: <span class="type">i32</span>,
diff --git a/crates/ra_ide_api/src/syntax_highlighting.rs b/crates/ra_ide_api/src/syntax_highlighting.rs
index 9ae2dc0610..1d290387c4 100644
--- a/crates/ra_ide_api/src/syntax_highlighting.rs
+++ b/crates/ra_ide_api/src/syntax_highlighting.rs
@@ -97,6 +97,9 @@ pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Vec<HighlightedRa
             STRING | RAW_STRING | RAW_BYTE_STRING | BYTE_STRING => "string",
             ATTR => "attribute",
             NAME_REF => {
+                if node.ancestors().any(|it| it.kind() == ATTR) {
+                    continue;
+                }
                 if let Some(name_ref) = node.as_node().cloned().and_then(ast::NameRef::cast) {
                     // FIXME: try to reuse the SourceAnalyzers
                     let analyzer = hir::SourceAnalyzer::new(db, file_id, name_ref.syntax(), None);
diff --git a/crates/ra_lsp_server/src/world.rs b/crates/ra_lsp_server/src/world.rs
index 27da751ab4..0eb684de5d 100644
--- a/crates/ra_lsp_server/src/world.rs
+++ b/crates/ra_lsp_server/src/world.rs
@@ -98,8 +98,12 @@ impl WorldState {
         }
 
         // FIXME: Read default cfgs from config
-        let default_cfg_options =
-            get_rustc_cfg_options().atom("test".into()).atom("debug_assertion".into());
+        let default_cfg_options = {
+            let mut opts = get_rustc_cfg_options();
+            opts.insert_atom("test".into());
+            opts.insert_atom("debug_assertion".into());
+            opts
+        };
 
         // Create crate graph from all the workspaces
         let mut crate_graph = CrateGraph::default();
diff --git a/crates/ra_project_model/src/lib.rs b/crates/ra_project_model/src/lib.rs
index 640a5ebd32..8b8663a78f 100644
--- a/crates/ra_project_model/src/lib.rs
+++ b/crates/ra_project_model/src/lib.rs
@@ -134,13 +134,16 @@ impl ProjectWorkspace {
                             json_project::Edition::Edition2015 => Edition::Edition2015,
                             json_project::Edition::Edition2018 => Edition::Edition2018,
                         };
-                        let mut cfg_options = default_cfg_options.clone();
-                        for name in &krate.atom_cfgs {
-                            cfg_options = cfg_options.atom(name.into());
-                        }
-                        for (key, value) in &krate.key_value_cfgs {
-                            cfg_options = cfg_options.key_value(key.into(), value.into());
-                        }
+                        let cfg_options = {
+                            let mut opts = default_cfg_options.clone();
+                            for name in &krate.atom_cfgs {
+                                opts.insert_atom(name.into());
+                            }
+                            for (key, value) in &krate.key_value_cfgs {
+                                opts.insert_key_value(key.into(), value.into());
+                            }
+                            opts
+                        };
                         crates.insert(
                             crate_id,
                             crate_graph.add_crate_root(file_id, edition, cfg_options),
@@ -171,7 +174,12 @@ impl ProjectWorkspace {
                 for krate in sysroot.crates() {
                     if let Some(file_id) = load(krate.root(&sysroot)) {
                         // Crates from sysroot have `cfg(test)` disabled
-                        let cfg_options = default_cfg_options.clone().remove_atom(&"test".into());
+                        let cfg_options = {
+                            let mut opts = default_cfg_options.clone();
+                            opts.remove_atom("test");
+                            opts
+                        };
+
                         let crate_id =
                             crate_graph.add_crate_root(file_id, Edition::Edition2018, cfg_options);
                         sysroot_crates.insert(krate, crate_id);
@@ -202,9 +210,11 @@ impl ProjectWorkspace {
                         let root = tgt.root(&cargo);
                         if let Some(file_id) = load(root) {
                             let edition = pkg.edition(&cargo);
-                            let cfg_options = default_cfg_options
-                                .clone()
-                                .features(pkg.features(&cargo).iter().map(Into::into));
+                            let cfg_options = {
+                                let mut opts = default_cfg_options.clone();
+                                opts.insert_features(pkg.features(&cargo).iter().map(Into::into));
+                                opts
+                            };
                             let crate_id =
                                 crate_graph.add_crate_root(file_id, edition, cfg_options);
                             names.insert(crate_id, pkg.name(&cargo).to_string());
@@ -310,6 +320,14 @@ fn find_cargo_toml(path: &Path) -> Result<PathBuf> {
 pub fn get_rustc_cfg_options() -> CfgOptions {
     let mut cfg_options = CfgOptions::default();
 
+    // Some nightly-only cfgs, which are required for stdlib
+    {
+        cfg_options.insert_atom("target_thread_local".into());
+        for &target_has_atomic in ["16", "32", "64", "8", "cas", "ptr"].iter() {
+            cfg_options.insert_key_value("target_has_atomic".into(), target_has_atomic.into())
+        }
+    }
+
     match (|| -> Result<_> {
         // `cfg(test)` and `cfg(debug_assertion)` are handled outside, so we suppress them here.
         let output = Command::new("rustc").args(&["--print", "cfg", "-O"]).output()?;
@@ -321,11 +339,11 @@ pub fn get_rustc_cfg_options() -> CfgOptions {
         Ok(rustc_cfgs) => {
             for line in rustc_cfgs.lines() {
                 match line.find('=') {
-                    None => cfg_options = cfg_options.atom(line.into()),
+                    None => cfg_options.insert_atom(line.into()),
                     Some(pos) => {
                         let key = &line[..pos];
                         let value = line[pos + 1..].trim_matches('"');
-                        cfg_options = cfg_options.key_value(key.into(), value.into());
+                        cfg_options.insert_key_value(key.into(), value.into());
                     }
                 }
             }


Test patch:
diff --git a/crates/ra_hir/src/nameres/tests.rs b/crates/ra_hir/src/nameres/tests.rs
index 34dd795743..8c6b40aaf2 100644
--- a/crates/ra_hir/src/nameres/tests.rs
+++ b/crates/ra_hir/src/nameres/tests.rs
@@ -7,7 +7,6 @@ mod mod_resolution;
 use std::sync::Arc;
 
 use insta::assert_snapshot;
-use ra_cfg::CfgOptions;
 use ra_db::SourceDatabase;
 use test_utils::covers;
 
@@ -561,12 +560,12 @@ fn cfg_test() {
         "#,
         crate_graph! {
             "main": ("/main.rs", ["std"]),
-            "std": ("/lib.rs", [], CfgOptions::default()
-                .atom("test".into())
-                .key_value("feature".into(), "foo".into())
-                .key_value("feature".into(), "bar".into())
-                .key_value("opt".into(), "42".into())
-            ),
+            "std": ("/lib.rs", [], cfg = {
+                "test",
+                "feature" = "foo",
+                "feature" = "bar",
+                "opt" = "42",
+            }),
         },
     );
 
diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs
index 25dad81eb7..263b61a59c 100644
--- a/crates/ra_hir/src/ty/tests.rs
+++ b/crates/ra_hir/src/ty/tests.rs
@@ -3,7 +3,6 @@ use std::sync::Arc;
 
 use insta::assert_snapshot;
 
-use ra_cfg::CfgOptions;
 use ra_db::{salsa::Database, FilePosition, SourceDatabase};
 use ra_syntax::{
     algo,
@@ -62,7 +61,7 @@ impl S {
 "#,
     );
     db.set_crate_graph_from_fixture(crate_graph! {
-        "main": ("/main.rs", ["foo"], CfgOptions::default().atom("test".into())),
+        "main": ("/main.rs", ["foo"], cfg = { "test" }),
         "foo": ("/foo.rs", []),
     });
     assert_eq!("(i32, {unknown}, i32, {unknown})", type_at_pos(&db, pos));