diff --git a/src/cargo/sources/registry/index/mod.rs b/src/cargo/sources/registry/index/mod.rs index eb745142680..c47e393eaf2 100644 --- a/src/cargo/sources/registry/index/mod.rs +++ b/src/cargo/sources/registry/index/mod.rs @@ -198,7 +198,8 @@ impl IndexSummary { #[derive(Deserialize, Serialize)] pub struct IndexPackage<'a> { /// Name of the package. - pub name: InternedString, + #[serde(borrow)] + pub name: Cow<'a, str>, /// The version of this dependency. pub vers: Version, /// All kinds of direct dependencies of the package, including dev and @@ -207,14 +208,14 @@ pub struct IndexPackage<'a> { pub deps: Vec>, /// Set of features defined for the package, i.e., `[features]` table. #[serde(default)] - pub features: BTreeMap>, + pub features: BTreeMap, Vec>>, /// This field contains features with new, extended syntax. Specifically, /// namespaced features (`dep:`) and weak dependencies (`pkg?/feat`). /// /// This is separated from `features` because versions older than 1.19 /// will fail to load due to not being able to parse the new syntax, even /// with a `Cargo.lock` file. - pub features2: Option>>, + pub features2: Option, Vec>>>, /// Checksum for verifying the integrity of the corresponding downloaded package. pub cksum: String, /// If `true`, Cargo will skip this version when resolving. @@ -226,7 +227,7 @@ pub struct IndexPackage<'a> { /// /// Added early 2018 (see ), /// can be `None` if published before then. - pub links: Option, + pub links: Option>, /// Required version of rust /// /// Corresponds to `package.rust-version`. @@ -263,7 +264,11 @@ impl IndexPackage<'_> { fn to_summary(&self, source_id: SourceId) -> CargoResult { // ****CAUTION**** Please be extremely careful with returning errors, see // `IndexSummary::parse` for details - let pkgid = PackageId::new(self.name.into(), self.vers.clone(), source_id); + let pkgid = PackageId::new( + InternedString::new(&self.name), + self.vers.clone(), + source_id, + ); let deps = self .deps .iter() @@ -272,24 +277,31 @@ impl IndexPackage<'_> { let mut features = self.features.clone(); if let Some(features2) = &self.features2 { for (name, values) in features2 { - features.entry(*name).or_default().extend(values); + features + .entry(name.clone()) + .or_default() + .extend(values.iter().cloned()); } } - let mut summary = Summary::new( - pkgid, - deps, - &features, - self.links, - self.rust_version.clone(), - )?; + let features = features + .into_iter() + .map(|(name, values)| { + ( + InternedString::new(&name), + values.iter().map(|v| InternedString::new(&v)).collect(), + ) + }) + .collect::>(); + let links = self.links.as_ref().map(|l| InternedString::new(&l)); + let mut summary = Summary::new(pkgid, deps, &features, links, self.rust_version.clone())?; summary.set_checksum(self.cksum.clone()); Ok(summary) } } #[derive(Deserialize, Serialize)] -struct IndexPackageMinimum { - name: InternedString, +struct IndexPackageMinimum<'a> { + name: Cow<'a, str>, vers: Version, } @@ -308,13 +320,14 @@ struct IndexPackageV { pub struct RegistryDependency<'a> { /// Name of the dependency. If the dependency is renamed, the original /// would be stored in [`RegistryDependency::package`]. - pub name: InternedString, + #[serde(borrow)] + pub name: Cow<'a, str>, /// The SemVer requirement for this dependency. #[serde(borrow)] pub req: Cow<'a, str>, /// Set of features enabled for this dependency. #[serde(default)] - pub features: Vec, + pub features: Vec>, /// Whether or not this is an optional dependency. #[serde(default)] pub optional: bool, @@ -329,7 +342,7 @@ pub struct RegistryDependency<'a> { // `None` if it is from the same index. pub registry: Option>, /// The original name if the dependency is renamed. - pub package: Option, + pub package: Option>, /// Whether or not this is a public dependency. Unstable. See [RFC 1977]. /// /// [RFC 1977]: https://rust-lang.github.io/rfcs/1977-public-private-dependencies.html @@ -759,7 +772,7 @@ impl IndexSummary { Ok((index, summary)) => (index, summary, true), Err(err) => { let Ok(IndexPackageMinimum { name, vers }) = - serde_json::from_slice::(line) + serde_json::from_slice::>(line) else { // If we can't recover, prefer the original error return Err(err); @@ -833,9 +846,10 @@ impl<'a> RegistryDependency<'a> { default }; - let mut dep = Dependency::parse(package.unwrap_or(name), Some(&req), id)?; + let interned_name = InternedString::new(package.as_ref().unwrap_or(&name)); + let mut dep = Dependency::parse(interned_name, Some(&req), id)?; if package.is_some() { - dep.set_explicit_name_in_toml(name); + dep.set_explicit_name_in_toml(InternedString::new(&name)); } let kind = match kind.as_deref().unwrap_or("") { "dev" => DepKind::Development, @@ -869,6 +883,7 @@ impl<'a> RegistryDependency<'a> { dep.set_artifact(artifact); } + let features = features.iter().map(|f| InternedString::new(&f)); dep.set_optional(optional) .set_default_features(default_features) .set_features(features)