aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/cfg/src/lib.rs16
-rw-r--r--crates/project_model/src/workspace.rs16
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
3mod cfg_expr; 3mod cfg_expr;
4mod dnf; 4mod dnf;
@@ -59,6 +59,20 @@ pub struct CfgDiff {
59} 59}
60 60
61impl CfgDiff { 61impl 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};
7use anyhow::{format_err, Context, Result}; 7use anyhow::{format_err, Context, Result};
8use base_db::{CrateDisplayName, CrateGraph, CrateId, CrateName, Edition, Env, FileId, ProcMacro}; 8use base_db::{CrateDisplayName, CrateGraph, CrateId, CrateName, Edition, Env, FileId, ProcMacro};
9use cargo_workspace::DepKind; 9use cargo_workspace::DepKind;
10use cfg::CfgOptions; 10use cfg::{CfgAtom, CfgDiff, CfgOptions};
11use paths::{AbsPath, AbsPathBuf}; 11use paths::{AbsPath, AbsPathBuf};
12use proc_macro_api::ProcMacroClient; 12use proc_macro_api::ProcMacroClient;
13use rustc_hash::{FxHashMap, FxHashSet}; 13use 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() {