diff options
-rw-r--r-- | crates/cfg/src/lib.rs | 16 | ||||
-rw-r--r-- | crates/project_model/src/workspace.rs | 16 |
2 files changed, 30 insertions, 2 deletions
diff --git a/crates/cfg/src/lib.rs b/crates/cfg/src/lib.rs index 03b8dd767..87bf0c925 100644 --- a/crates/cfg/src/lib.rs +++ b/crates/cfg/src/lib.rs | |||
@@ -1,4 +1,4 @@ | |||
1 | //! cfg defines conditional compiling options, `cfg` attibute parser and evaluator | 1 | //! cfg defines conditional compiling options, `cfg` attribute parser and evaluator |
2 | 2 | ||
3 | mod cfg_expr; | 3 | mod cfg_expr; |
4 | mod dnf; | 4 | mod dnf; |
@@ -59,6 +59,20 @@ pub struct CfgDiff { | |||
59 | } | 59 | } |
60 | 60 | ||
61 | impl CfgDiff { | 61 | impl CfgDiff { |
62 | /// Create a new CfgDiff. Will return None if the same item appears more than once in the set | ||
63 | /// of both. | ||
64 | pub fn new(enable: Vec<CfgAtom>, disable: Vec<CfgAtom>) -> Option<CfgDiff> { | ||
65 | let mut occupied = FxHashSet::default(); | ||
66 | for item in enable.iter().chain(disable.iter()) { | ||
67 | if !occupied.insert(item) { | ||
68 | // was present | ||
69 | return None; | ||
70 | } | ||
71 | } | ||
72 | |||
73 | Some(CfgDiff { enable, disable }) | ||
74 | } | ||
75 | |||
62 | /// Returns the total number of atoms changed by this diff. | 76 | /// Returns the total number of atoms changed by this diff. |
63 | pub fn len(&self) -> usize { | 77 | pub fn len(&self) -> usize { |
64 | self.enable.len() + self.disable.len() | 78 | self.enable.len() + self.disable.len() |
diff --git a/crates/project_model/src/workspace.rs b/crates/project_model/src/workspace.rs index ef0f3c9e4..c2edb3327 100644 --- a/crates/project_model/src/workspace.rs +++ b/crates/project_model/src/workspace.rs | |||
@@ -7,7 +7,7 @@ use std::{collections::VecDeque, fmt, fs, path::Path, process::Command}; | |||
7 | use anyhow::{format_err, Context, Result}; | 7 | use anyhow::{format_err, Context, Result}; |
8 | use base_db::{CrateDisplayName, CrateGraph, CrateId, CrateName, Edition, Env, FileId, ProcMacro}; | 8 | use base_db::{CrateDisplayName, CrateGraph, CrateId, CrateName, Edition, Env, FileId, ProcMacro}; |
9 | use cargo_workspace::DepKind; | 9 | use cargo_workspace::DepKind; |
10 | use cfg::CfgOptions; | 10 | use cfg::{CfgAtom, CfgDiff, CfgOptions}; |
11 | use paths::{AbsPath, AbsPathBuf}; | 11 | use paths::{AbsPath, AbsPathBuf}; |
12 | use proc_macro_api::ProcMacroClient; | 12 | use proc_macro_api::ProcMacroClient; |
13 | use rustc_hash::{FxHashMap, FxHashSet}; | 13 | use rustc_hash::{FxHashMap, FxHashSet}; |
@@ -425,6 +425,20 @@ fn cargo_to_crate_graph( | |||
425 | let mut has_private = false; | 425 | let mut has_private = false; |
426 | // Next, create crates for each package, target pair | 426 | // Next, create crates for each package, target pair |
427 | for pkg in cargo.packages() { | 427 | for pkg in cargo.packages() { |
428 | let mut cfg_options = &cfg_options; | ||
429 | let mut replaced_cfg_options; | ||
430 | if cargo[pkg].name == "core" { | ||
431 | // FIXME: in the specific case of libcore in rust-lang/rust (i.e. it is not coming from | ||
432 | // a sysroot), there's a `#![cfg(not(test))]` at the top of it that makes its contents | ||
433 | // get ignored by r-a. We should implement a more general solution for this | ||
434 | |||
435 | replaced_cfg_options = cfg_options.clone(); | ||
436 | replaced_cfg_options.apply_diff( | ||
437 | CfgDiff::new(Default::default(), vec![CfgAtom::Flag("test".into())]).unwrap(), | ||
438 | ); | ||
439 | cfg_options = &replaced_cfg_options; | ||
440 | }; | ||
441 | |||
428 | has_private |= cargo[pkg].metadata.rustc_private; | 442 | has_private |= cargo[pkg].metadata.rustc_private; |
429 | let mut lib_tgt = None; | 443 | let mut lib_tgt = None; |
430 | for &tgt in cargo[pkg].targets.iter() { | 444 | for &tgt in cargo[pkg].targets.iter() { |