Skip to content

Commit 163de44

Browse files
committed
Auto merge of #3742 - matklad:sets-are-monoid, r=alexcrichton
Simplify feature-handling code A neat (imo :) ) hack to use an empty `&HashSet` instead of `Option<&HashSet>`.
2 parents b2dc77f + 50f1c17 commit 163de44

File tree

7 files changed

+32
-56
lines changed

7 files changed

+32
-56
lines changed

src/cargo/core/resolver/encode.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ impl EncodableResolve {
154154

155155
Ok(Resolve {
156156
graph: g,
157+
empty_features: HashSet::new(),
157158
features: HashMap::new(),
158159
replacements: replacements,
159160
checksums: checksums,

src/cargo/core/resolver/mod.rs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
4848
use std::cmp::Ordering;
4949
use std::collections::{HashSet, HashMap, BinaryHeap, BTreeMap};
50+
use std::iter::FromIterator;
5051
use std::fmt;
5152
use std::ops::Range;
5253
use std::rc::Rc;
@@ -74,6 +75,7 @@ mod encode;
7475
pub struct Resolve {
7576
graph: Graph<PackageId>,
7677
replacements: HashMap<PackageId, PackageId>,
78+
empty_features: HashSet<String>,
7779
features: HashMap<PackageId, HashSet<String>>,
7880
checksums: HashMap<PackageId, Option<String>>,
7981
metadata: Metadata,
@@ -210,8 +212,14 @@ unable to verify that `{0}` is the same as when the lockfile was generated
210212
&self.replacements
211213
}
212214

213-
pub fn features(&self, pkg: &PackageId) -> Option<&HashSet<String>> {
214-
self.features.get(pkg)
215+
pub fn features(&self, pkg: &PackageId) -> &HashSet<String> {
216+
self.features.get(pkg).unwrap_or(&self.empty_features)
217+
}
218+
219+
pub fn features_sorted(&self, pkg: &PackageId) -> Vec<&str> {
220+
let mut v = Vec::from_iter(self.features(pkg).iter().map(|s| s.as_ref()));
221+
v.sort();
222+
v
215223
}
216224

217225
pub fn query(&self, spec: &str) -> CargoResult<&PackageId> {
@@ -273,6 +281,7 @@ pub fn resolve(summaries: &[(Summary, Method)],
273281

274282
let mut resolve = Resolve {
275283
graph: cx.resolve_graph,
284+
empty_features: HashSet::new(),
276285
features: cx.resolve_features,
277286
checksums: HashMap::new(),
278287
metadata: BTreeMap::new(),

src/cargo/ops/cargo_compile.rs

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -283,19 +283,14 @@ pub fn compile_ws<'a>(ws: &Workspace<'a>,
283283
fn resolve_all_features(resolve_with_overrides: &Resolve,
284284
package_id: &PackageId)
285285
-> HashSet<String> {
286-
let mut features = match resolve_with_overrides.features(package_id) {
287-
Some(all_features) => all_features.clone(),
288-
None => HashSet::new(),
289-
};
286+
let mut features = resolve_with_overrides.features(package_id).clone();
290287

291288
// Include features enabled for use by dependencies so targets can also use them with the
292289
// required-features field when deciding whether to be built or skipped.
293290
let deps = resolve_with_overrides.deps(package_id);
294291
for dep in deps {
295-
if let Some(dep_features) = resolve_with_overrides.features(dep) {
296-
for feature in dep_features {
297-
features.insert(dep.name().to_string() + "/" + feature);
298-
}
292+
for feature in resolve_with_overrides.features(dep) {
293+
features.insert(dep.name().to_string() + "/" + feature);
299294
}
300295
}
301296

src/cargo/ops/cargo_rustc/context.rs

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -401,14 +401,7 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
401401

402402
// Also mix in enabled features to our metadata. This'll ensure that
403403
// when changing feature sets each lib is separately cached.
404-
match self.resolve.features(unit.pkg.package_id()) {
405-
Some(features) => {
406-
let mut feat_vec: Vec<&String> = features.iter().collect();
407-
feat_vec.sort();
408-
feat_vec.hash(&mut hasher);
409-
}
410-
None => Vec::<&String>::new().hash(&mut hasher),
411-
}
404+
self.resolve.features_sorted(unit.pkg.package_id()).hash(&mut hasher);
412405

413406
// Throw in the profile we're compiling with. This helps caching
414407
// panic=abort and panic=unwind artifacts, additionally with various
@@ -601,11 +594,8 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
601594

602595
// If the dependency is optional, then we're only activating it
603596
// if the corresponding feature was activated
604-
if d.is_optional() {
605-
match self.resolve.features(id) {
606-
Some(f) if f.contains(d.name()) => {}
607-
_ => return false,
608-
}
597+
if d.is_optional() && !self.resolve.features(id).contains(d.name()) {
598+
return false;
609599
}
610600

611601
// If we've gotten past all that, then this dependency is

src/cargo/ops/cargo_rustc/custom_build.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -120,10 +120,8 @@ fn build_work<'a, 'cfg>(cx: &mut Context<'a, 'cfg>, unit: &Unit<'a>)
120120

121121
// Be sure to pass along all enabled features for this package, this is the
122122
// last piece of statically known information that we have.
123-
if let Some(features) = cx.resolve.features(unit.pkg.package_id()) {
124-
for feat in features.iter() {
125-
cmd.env(&format!("CARGO_FEATURE_{}", super::envify(feat)), "1");
126-
}
123+
for feat in cx.resolve.features(unit.pkg.package_id()).iter() {
124+
cmd.env(&format!("CARGO_FEATURE_{}", super::envify(feat)), "1");
127125
}
128126

129127
let mut cfg_map = HashMap::new();

src/cargo/ops/cargo_rustc/fingerprint.rs

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -319,16 +319,6 @@ fn calculate<'a, 'cfg>(cx: &mut Context<'a, 'cfg>, unit: &Unit<'a>)
319319
return Ok(s.clone())
320320
}
321321

322-
// First, calculate all statically known "salt data" such as the profile
323-
// information (compiler flags), the compiler version, activated features,
324-
// and target configuration.
325-
let features = cx.resolve.features(unit.pkg.package_id());
326-
let features = features.map(|s| {
327-
let mut v = s.iter().collect::<Vec<_>>();
328-
v.sort();
329-
v
330-
});
331-
332322
// Next, recursively calculate the fingerprint for all of our dependencies.
333323
//
334324
// Skip the fingerprints of build scripts as they may not always be
@@ -365,7 +355,7 @@ fn calculate<'a, 'cfg>(cx: &mut Context<'a, 'cfg>, unit: &Unit<'a>)
365355
rustc: util::hash_u64(&cx.config.rustc()?.verbose_version),
366356
target: util::hash_u64(&unit.target),
367357
profile: util::hash_u64(&unit.profile),
368-
features: format!("{:?}", features),
358+
features: format!("{:?}", cx.resolve.features_sorted(unit.pkg.package_id())),
369359
deps: deps,
370360
local: local,
371361
memoized_hash: Mutex::new(None),

src/cargo/ops/cargo_rustc/mod.rs

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -182,11 +182,10 @@ pub fn compile_targets<'a, 'cfg: 'a>(ws: &Workspace<'cfg>,
182182
}
183183
}
184184

185-
if let Some(feats) = cx.resolve.features(unit.pkg.package_id()) {
186-
cx.compilation.cfgs.entry(unit.pkg.package_id().clone())
187-
.or_insert_with(HashSet::new)
188-
.extend(feats.iter().map(|feat| format!("feature=\"{}\"", feat)));
189-
}
185+
let feats = cx.resolve.features(&unit.pkg.package_id());
186+
cx.compilation.cfgs.entry(unit.pkg.package_id().clone())
187+
.or_insert_with(HashSet::new)
188+
.extend(feats.iter().map(|feat| format!("feature=\"{}\"", feat)));
190189

191190
output_depinfo(&mut cx, unit)?;
192191
}
@@ -293,11 +292,9 @@ fn rustc(cx: &mut Context, unit: &Unit, exec: Arc<Executor>) -> CargoResult<Work
293292
let package_id = unit.pkg.package_id().clone();
294293
let target = unit.target.clone();
295294
let profile = unit.profile.clone();
296-
let features = cx.resolve.features(unit.pkg.package_id())
297-
.into_iter()
298-
.flat_map(|i| i)
299-
.map(|s| s.to_string())
300-
.collect::<Vec<_>>();
295+
let features = cx.resolve.features(unit.pkg.package_id()).iter()
296+
.map(|s| s.to_owned())
297+
.collect();
301298

302299
exec.init(cx);
303300
let exec = exec.clone();
@@ -533,10 +530,8 @@ fn rustdoc(cx: &mut Context, unit: &Unit) -> CargoResult<Work> {
533530

534531
rustdoc.arg("-o").arg(doc_dir);
535532

536-
if let Some(features) = cx.resolve.features(unit.pkg.package_id()) {
537-
for feat in features {
538-
rustdoc.arg("--cfg").arg(&format!("feature=\"{}\"", feat));
539-
}
533+
for feat in cx.resolve.features(unit.pkg.package_id()) {
534+
rustdoc.arg("--cfg").arg(&format!("feature=\"{}\"", feat));
540535
}
541536

542537
if let Some(ref args) = unit.profile.rustdoc_args {
@@ -684,10 +679,8 @@ fn build_base_args(cx: &mut Context,
684679
cmd.arg("--cfg").arg("test");
685680
}
686681

687-
if let Some(features) = cx.resolve.features(unit.pkg.package_id()) {
688-
for feat in features.iter() {
689-
cmd.arg("--cfg").arg(&format!("feature=\"{}\"", feat));
690-
}
682+
for feat in cx.resolve.features(unit.pkg.package_id()).iter() {
683+
cmd.arg("--cfg").arg(&format!("feature=\"{}\"", feat));
691684
}
692685

693686
match cx.target_metadata(unit) {

0 commit comments

Comments
 (0)