diff --git a/src/cargo/core/resolver/features.rs b/src/cargo/core/resolver/features.rs index acbdec424b3..cea01d113a4 100644 --- a/src/cargo/core/resolver/features.rs +++ b/src/cargo/core/resolver/features.rs @@ -208,36 +208,34 @@ impl ResolvedFeatures { pkg_id: PackageId, features_for: FeaturesFor, ) -> Vec { - self.activated_features_int(pkg_id, features_for, true) + self.activated_features_int(pkg_id, features_for) + .expect("activated_features for invalid package") } - /// Variant of `activated_features` that returns an empty Vec if this is + /// Variant of `activated_features` that returns `None` if this is /// not a valid pkg_id/is_build combination. Used in places which do /// not know which packages are activated (like `cargo clean`). pub fn activated_features_unverified( &self, pkg_id: PackageId, features_for: FeaturesFor, - ) -> Vec { - self.activated_features_int(pkg_id, features_for, false) + ) -> Option> { + self.activated_features_int(pkg_id, features_for).ok() } fn activated_features_int( &self, pkg_id: PackageId, features_for: FeaturesFor, - verify: bool, - ) -> Vec { + ) -> CargoResult> { if let Some(legacy) = &self.legacy { - legacy.get(&pkg_id).map_or_else(Vec::new, |v| v.clone()) + Ok(legacy.get(&pkg_id).map_or_else(Vec::new, |v| v.clone())) } else { let is_build = self.opts.decouple_host_deps && features_for == FeaturesFor::HostDep; if let Some(fs) = self.activated_features.get(&(pkg_id, is_build)) { - fs.iter().cloned().collect() - } else if verify { - panic!("features did not find {:?} {:?}", pkg_id, is_build) + Ok(fs.iter().cloned().collect()) } else { - Vec::new() + anyhow::bail!("features did not find {:?} {:?}", pkg_id, is_build) } } } diff --git a/src/cargo/ops/cargo_clean.rs b/src/cargo/ops/cargo_clean.rs index beb9b03cd39..0a4166940e3 100644 --- a/src/cargo/ops/cargo_clean.rs +++ b/src/cargo/ops/cargo_clean.rs @@ -129,8 +129,9 @@ pub fn clean(ws: &Workspace<'_>, opts: &CleanOptions<'_>) -> CargoResult<()> { // Use unverified here since this is being more // exhaustive than what is actually needed. let features_for = unit_for.map_to_features_for(); - let features = - features.activated_features_unverified(pkg.package_id(), features_for); + let features = features + .activated_features_unverified(pkg.package_id(), features_for) + .unwrap_or_default(); units.push(interner.intern( pkg, target, profile, *kind, *mode, features, /*is_std*/ false, )); diff --git a/src/cargo/ops/cargo_compile.rs b/src/cargo/ops/cargo_compile.rs index 29e3abf018e..762da60b02b 100644 --- a/src/cargo/ops/cargo_compile.rs +++ b/src/cargo/ops/cargo_compile.rs @@ -978,7 +978,10 @@ pub fn resolve_all_features( .proc_macro(); for dep in deps { let features_for = FeaturesFor::from_for_host(is_proc_macro || dep.is_build()); - for feature in resolved_features.activated_features_unverified(dep_id, features_for) { + for feature in resolved_features + .activated_features_unverified(dep_id, features_for) + .unwrap_or_default() + { features.insert(format!("{}/{}", dep.name_in_toml(), feature)); } }