Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions src/cargo/core/dependency.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ struct Inner {

optional: bool,
default_features: bool,
features: Vec<String>,
features: Vec<InternedString>,

// This dependency should be used only for this platform.
// `None` means *all platforms*.
Expand Down Expand Up @@ -64,14 +64,15 @@ impl ser::Serialize for Dependency {
where
S: ser::Serializer,
{
let string_features: Vec<_> = self.features().iter().map(|s| s.to_string()).collect();
SerializedDependency {
name: &*self.name(),
source: self.source_id(),
req: self.version_req().to_string(),
kind: self.kind(),
optional: self.is_optional(),
uses_default_features: self.uses_default_features(),
features: self.features(),
features: &string_features,
target: self.platform(),
rename: self.rename(),
}.serialize(s)
Expand Down Expand Up @@ -250,7 +251,8 @@ impl Dependency {

/// Sets the list of features requested for the package.
pub fn set_features(&mut self, features: Vec<String>) -> &mut Dependency {
Rc::make_mut(&mut self.inner).features = features;
Rc::make_mut(&mut self.inner).features =
features.iter().map(|s| InternedString::new(s)).collect();
self
}

Expand Down Expand Up @@ -334,7 +336,7 @@ impl Dependency {
self.inner.default_features
}
/// Returns the list of features that are requested by the dependency.
pub fn features(&self) -> &[String] {
pub fn features(&self) -> &[InternedString] {
&self.inner.features
}

Expand Down
20 changes: 10 additions & 10 deletions src/cargo/core/resolver/context.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
use std::collections::{HashMap, HashSet};
use std::rc::Rc;

use core::{Dependency, FeatureValue, PackageId, SourceId, Summary};
use core::interning::InternedString;
use util::Graph;
use core::{Dependency, FeatureValue, PackageId, SourceId, Summary};
use util::CargoResult;
use util::Graph;

use super::types::{ActivateResult, ConflictReason, DepInfo, GraphNode, Method, RcList};
use super::types::RegistryQueryer;
use super::types::{ActivateResult, ConflictReason, DepInfo, GraphNode, Method, RcList};

pub use super::encode::{EncodableDependency, EncodablePackageId, EncodableResolve};
pub use super::encode::{Metadata, WorkspaceResolve};
Expand Down Expand Up @@ -160,7 +160,7 @@ impl Context {
parent: Option<&Summary>,
s: &'b Summary,
method: &'b Method,
) -> ActivateResult<Vec<(Dependency, Vec<String>)>> {
) -> ActivateResult<Vec<(Dependency, Vec<InternedString>)>> {
let dev_deps = match *method {
Method::Everything => true,
Method::Required { dev_deps, .. } => dev_deps,
Expand All @@ -182,7 +182,7 @@ impl Context {
{
requested
.iter()
.map(|f| FeatureValue::new(f, s))
.map(|&f| FeatureValue::new(f, s))
.collect::<Vec<FeatureValue>>()
} else {
vec![]
Expand Down Expand Up @@ -210,7 +210,7 @@ impl Context {
));
}
let mut base = base.1;
base.extend(dep.features().iter().cloned());
base.extend(dep.features().iter());
for feature in base.iter() {
if feature.contains('/') {
return Err(
Expand Down Expand Up @@ -331,7 +331,7 @@ struct Requirements<'a> {
// specified set of features enabled. The boolean indicates whether this
// package was specifically requested (rather than just requesting features
// *within* this package).
deps: HashMap<&'a str, (bool, Vec<String>)>,
deps: HashMap<&'a str, (bool, Vec<InternedString>)>,
// The used features set is the set of features which this local package had
// enabled, which is later used when compiling to instruct the code what
// features were enabled.
Expand All @@ -349,13 +349,13 @@ impl<'r> Requirements<'r> {
}
}

fn require_crate_feature(&mut self, package: &'r str, feat: &'r str) {
fn require_crate_feature(&mut self, package: &'r str, feat: InternedString) {
self.used.insert(package);
self.deps
.entry(package)
.or_insert((false, Vec::new()))
.1
.push(feat.to_string());
.push(feat);
}

fn seen(&mut self, feat: &'r str) -> bool {
Expand Down Expand Up @@ -399,7 +399,7 @@ impl<'r> Requirements<'r> {
match *fv {
FeatureValue::Feature(ref feat) => self.require_feature(feat),
FeatureValue::Crate(ref dep) => Ok(self.require_dependency(dep)),
FeatureValue::CrateFeature(ref dep, ref dep_feat) => {
FeatureValue::CrateFeature(ref dep, dep_feat) => {
Ok(self.require_crate_feature(dep, dep_feat))
}
}
Expand Down
3 changes: 2 additions & 1 deletion src/cargo/core/resolver/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ use semver;

use core::{Dependency, PackageId, Registry, Summary};
use core::PackageIdSpec;
use core::interning::InternedString;
use util::config::Config;
use util::Graph;
use util::errors::{CargoError, CargoResult};
Expand Down Expand Up @@ -670,7 +671,7 @@ struct BacktrackFrame {
remaining_candidates: RemainingCandidates,
parent: Summary,
dep: Dependency,
features: Rc<Vec<String>>,
features: Rc<Vec<InternedString>>,
conflicting_activations: HashMap<PackageId, ConflictReason>,
}

Expand Down
11 changes: 6 additions & 5 deletions src/cargo/core/resolver/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use std::ops::Range;
use std::rc::Rc;

use core::{Dependency, PackageId, PackageIdSpec, Registry, Summary};
use core::interning::InternedString;
use util::{CargoError, CargoResult};

pub struct RegistryQueryer<'a> {
Expand Down Expand Up @@ -159,21 +160,21 @@ pub enum Method<'a> {
Everything, // equivalent to Required { dev_deps: true, all_features: true, .. }
Required {
dev_deps: bool,
features: &'a [String],
features: &'a [InternedString],
all_features: bool,
uses_default_features: bool,
},
}

impl<'r> Method<'r> {
pub fn split_features(features: &[String]) -> Vec<String> {
pub fn split_features(features: &[String]) -> Vec<InternedString> {
features
.iter()
.flat_map(|s| s.split_whitespace())
.flat_map(|s| s.split(','))
.filter(|s| !s.is_empty())
.map(|s| s.to_string())
.collect::<Vec<String>>()
.map(|s| InternedString::new(s))
.collect::<Vec<InternedString>>()
}
}

Expand Down Expand Up @@ -245,7 +246,7 @@ impl Ord for DepsFrame {
// Information about the dependencies for a crate, a tuple of:
//
// (dependency info, candidates, features activated)
pub type DepInfo = (Dependency, Rc<Vec<Candidate>>, Rc<Vec<String>>);
pub type DepInfo = (Dependency, Rc<Vec<Candidate>>, Rc<Vec<InternedString>>);

pub type ActivateResult<T> = Result<T, ActivateError>;

Expand Down
17 changes: 8 additions & 9 deletions src/cargo/core/summary.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,11 @@ use std::collections::BTreeMap;
use std::mem;
use std::rc::Rc;

use semver::Version;

use serde::{Serialize, Serializer};

use core::{Dependency, PackageId, SourceId};
use core::interning::InternedString;
use core::{Dependency, PackageId, SourceId};
use semver::Version;

use util::CargoResult;

Expand Down Expand Up @@ -138,7 +137,7 @@ fn build_feature_map(
for (feature, list) in features.iter() {
let mut values = vec![];
for dep in list {
let val = FeatureValue::build(dep, |fs| (&features).get(fs).is_some());
let val = FeatureValue::build(InternedString::new(dep), |fs| features.contains_key(fs));
if let &Feature(_) = &val {
values.push(val);
continue;
Expand Down Expand Up @@ -201,7 +200,7 @@ pub enum FeatureValue {
}

impl FeatureValue {
fn build<T>(feature: &str, is_feature: T) -> FeatureValue
fn build<T>(feature: InternedString, is_feature: T) -> FeatureValue
where
T: Fn(&str) -> bool,
{
Expand All @@ -211,13 +210,13 @@ impl FeatureValue {
let dep_feat = &dep_feat[1..];
FeatureValue::CrateFeature(InternedString::new(dep), InternedString::new(dep_feat))
}
None if is_feature(&feature) => FeatureValue::Feature(InternedString::new(feature)),
None => FeatureValue::Crate(InternedString::new(feature)),
None if is_feature(&feature) => FeatureValue::Feature(feature),
None => FeatureValue::Crate(feature),
}
}

pub fn new(feature: &str, s: &Summary) -> FeatureValue {
Self::build(feature, |fs| s.features().get(fs).is_some())
pub fn new(feature: InternedString, s: &Summary) -> FeatureValue {
Self::build(feature, |fs| s.features().contains_key(fs))
}

pub fn to_string(&self) -> String {
Expand Down
2 changes: 1 addition & 1 deletion src/cargo/ops/registry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ fn transmit(
optional: dep.is_optional(),
default_features: dep.uses_default_features(),
name: dep.name().to_string(),
features: dep.features().to_vec(),
features: dep.features().iter().map(|s| s.to_string()).collect(),
version_req: dep.version_req().to_string(),
target: dep.platform().map(|s| s.to_string()),
kind: match dep.kind() {
Expand Down
8 changes: 5 additions & 3 deletions src/cargo/ops/resolve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -472,9 +472,11 @@ fn register_previous_locks<'a>(
// dependency on that crate to enable the feature. For now
// this bug is better than the always updating registry
// though...
if !ws.members().any(|pkg| pkg.package_id() == member.package_id()) &&
(dep.is_optional() || !dep.is_transitive()) {
continue
if !ws.members()
.any(|pkg| pkg.package_id() == member.package_id())
&& (dep.is_optional() || !dep.is_transitive())
{
continue;
}

// Ok if nothing matches, then we poison the source of this
Expand Down