From 355419d4044704d13a902641d86ad5501af8714d Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 8 Oct 2019 14:22:49 +0300 Subject: [PATCH 1/4] use slightly more idiomatic api for cfg --- crates/ra_batch/src/lib.rs | 8 +++++-- crates/ra_cfg/src/lib.rs | 24 ++++++++------------ crates/ra_hir/src/nameres/tests.rs | 14 +++++++----- crates/ra_hir/src/ty/tests.rs | 6 ++++- crates/ra_ide_api/src/lib.rs | 3 ++- crates/ra_lsp_server/src/world.rs | 8 +++++-- crates/ra_project_model/src/lib.rs | 36 +++++++++++++++++++----------- 7 files changed, 59 insertions(+), 40 deletions(-) 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 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 { + pub fn remove_atom(&mut self, name: &str) { + self.atoms.remove(name); + } + + pub fn insert_key_value(&mut self, key: SmolStr, value: SmolStr) { self.key_values.insert((key, value)); - self } /// Shortcut to set features - pub fn features(mut self, iter: impl IntoIterator) -> CfgOptions { - for feat in iter { - self = self.key_value("feature".into(), feat); - } - self - } - - pub fn remove_atom(mut self, name: &SmolStr) -> CfgOptions { - self.atoms.remove(name); - self + pub fn insert_features(&mut self, iter: impl IntoIterator) { + iter.into_iter().for_each(|feat| self.insert_key_value("feature".into(), feat)); } } diff --git a/crates/ra_hir/src/nameres/tests.rs b/crates/ra_hir/src/nameres/tests.rs index 34dd795743..208c2f16f0 100644 --- a/crates/ra_hir/src/nameres/tests.rs +++ b/crates/ra_hir/src/nameres/tests.rs @@ -561,12 +561,14 @@ 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", [], { + let mut opts = CfgOptions::default(); + opts.insert_atom("test".into()); + opts.insert_key_value("feature".into(), "foo".into()); + opts.insert_key_value("feature".into(), "bar".into()); + opts.insert_key_value("opt".into(), "42".into()); + opts + }), }, ); diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs index 25dad81eb7..b16b482581 100644 --- a/crates/ra_hir/src/ty/tests.rs +++ b/crates/ra_hir/src/ty/tests.rs @@ -62,7 +62,11 @@ impl S { "#, ); db.set_crate_graph_from_fixture(crate_graph! { - "main": ("/main.rs", ["foo"], CfgOptions::default().atom("test".into())), + "main": ("/main.rs", ["foo"], { + let mut opts = CfgOptions::default(); + opts.insert_atom("test".into()); + opts + }), "foo": ("/foo.rs", []), }); assert_eq!("(i32, {unknown}, i32, {unknown})", type_at_pos(&db, pos)); 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_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..a4d117e34f 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()); @@ -321,11 +331,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()); } } } From 972079c0e32ba6085eb5ba02a137a6df86b79b5a Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 8 Oct 2019 14:39:44 +0300 Subject: [PATCH 2/4] macro DSL for cfg in tests --- crates/ra_hir/src/mock.rs | 19 +++++++++++++++++-- crates/ra_hir/src/nameres/tests.rs | 13 +++++-------- crates/ra_hir/src/ty/tests.rs | 7 +------ 3 files changed, 23 insertions(+), 16 deletions(-) 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_hir/src/nameres/tests.rs b/crates/ra_hir/src/nameres/tests.rs index 208c2f16f0..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,13 +560,11 @@ fn cfg_test() { "#, crate_graph! { "main": ("/main.rs", ["std"]), - "std": ("/lib.rs", [], { - let mut opts = CfgOptions::default(); - opts.insert_atom("test".into()); - opts.insert_key_value("feature".into(), "foo".into()); - opts.insert_key_value("feature".into(), "bar".into()); - opts.insert_key_value("opt".into(), "42".into()); - opts + "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 b16b482581..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,11 +61,7 @@ impl S { "#, ); db.set_crate_graph_from_fixture(crate_graph! { - "main": ("/main.rs", ["foo"], { - let mut opts = CfgOptions::default(); - opts.insert_atom("test".into()); - opts - }), + "main": ("/main.rs", ["foo"], cfg = { "test" }), "foo": ("/foo.rs", []), }); assert_eq!("(i32, {unknown}, i32, {unknown})", type_at_pos(&db, pos)); From 857f419c9ded5ebeab428535729b57687499d3a6 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 8 Oct 2019 14:43:29 +0300 Subject: [PATCH 3/4] hard-code nightly-only CFGs --- crates/ra_project_model/src/lib.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/crates/ra_project_model/src/lib.rs b/crates/ra_project_model/src/lib.rs index a4d117e34f..8b8663a78f 100644 --- a/crates/ra_project_model/src/lib.rs +++ b/crates/ra_project_model/src/lib.rs @@ -320,6 +320,14 @@ fn find_cargo_toml(path: &Path) -> Result { 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()?; From 6503add6e3c900ea7ded37199ea58f43bb57b051 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 8 Oct 2019 14:52:03 +0300 Subject: [PATCH 4/4] restore coloring of attributes --- crates/ra_ide_api/src/snapshots/highlighting.html | 2 +- crates/ra_ide_api/src/syntax_highlighting.rs | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) 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; } -
#[derive(Clone, Debug)]
+
#[derive(Clone, Debug)]
 struct Foo {
     pub x: i32,
     pub y: i32,
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 "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);