diff --git a/src/project/manifest/feature.rs b/src/project/manifest/feature.rs index c49506561..abd8f9372 100644 --- a/src/project/manifest/feature.rs +++ b/src/project/manifest/feature.rs @@ -107,7 +107,7 @@ impl fmt::Display for FeatureName { /// /// Individual features cannot be used directly, instead they are grouped together into /// environments. Environments are then locked and installed. -#[derive(Debug, Clone, Default)] +#[derive(Debug, Clone)] pub struct Feature { /// The name of the feature or `None` if the feature is the default feature. pub name: FeatureName, @@ -132,6 +132,17 @@ pub struct Feature { } impl Feature { + /// Construct a new feature with the given name. + pub fn new(name: FeatureName) -> Self { + Feature { + name, + platforms: None, + channels: None, + system_requirements: SystemRequirements::default(), + targets: ::default(), + } + } + /// Returns true if this feature is the default feature. pub fn is_default(&self) -> bool { self.name == FeatureName::Default diff --git a/src/project/manifest/mod.rs b/src/project/manifest/mod.rs index 73781a47d..62eef0aed 100644 --- a/src/project/manifest/mod.rs +++ b/src/project/manifest/mod.rs @@ -698,7 +698,11 @@ impl Manifest { name: Option<&FeatureName>, ) -> &mut Target { let feature = match name { - Some(feature) => self.parsed.features.entry(feature.clone()).or_default(), + Some(feature) => self + .parsed + .features + .entry(feature.clone()) + .or_insert_with(|| Feature::new(feature.clone())), None => self.default_feature_mut(), }; feature diff --git a/src/project/manifest/pyproject.rs b/src/project/manifest/pyproject.rs index d102d7412..426844ac8 100644 --- a/src/project/manifest/pyproject.rs +++ b/src/project/manifest/pyproject.rs @@ -16,7 +16,7 @@ use crate::FeatureName; use super::{ error::{RequirementConversionError, TomlError}, python::PyPiPackageName, - ProjectManifest, PyPiRequirement, SpecType, + Feature, ProjectManifest, PyPiRequirement, SpecType, }; #[derive(Deserialize, Debug, Clone)] @@ -106,10 +106,11 @@ impl From for ProjectManifest { for (extra, reqs) in extras { // Filter out unused features if features_used.contains(extra) { + let feature_name = FeatureName::Named(extra.to_string()); let target = manifest .features - .entry(FeatureName::Named(extra.to_string())) - .or_default() + .entry(feature_name.clone()) + .or_insert_with(move || Feature::new(feature_name)) .targets .default_mut(); for req in reqs.iter() {