]> git.proxmox.com Git - cargo.git/commitdiff
Move string interning to util
authorest31 <MTest31@outlook.com>
Fri, 26 Jun 2020 17:46:20 +0000 (19:46 +0200)
committerest31 <MTest31@outlook.com>
Fri, 26 Jun 2020 17:55:29 +0000 (19:55 +0200)
Code that handles string interning is rather an util functionality than
a core functionality.

40 files changed:
src/cargo/core/compiler/build_config.rs
src/cargo/core/compiler/build_context/mod.rs
src/cargo/core/compiler/compile_kind.rs
src/cargo/core/compiler/fingerprint.rs
src/cargo/core/compiler/lto.rs
src/cargo/core/compiler/mod.rs
src/cargo/core/compiler/unit.rs
src/cargo/core/compiler/unit_dependencies.rs
src/cargo/core/compiler/unit_graph.rs
src/cargo/core/dependency.rs
src/cargo/core/interning.rs [deleted file]
src/cargo/core/manifest.rs
src/cargo/core/mod.rs
src/cargo/core/package.rs
src/cargo/core/package_id.rs
src/cargo/core/package_id_spec.rs
src/cargo/core/profiles.rs
src/cargo/core/registry.rs
src/cargo/core/resolver/context.rs
src/cargo/core/resolver/dep_cache.rs
src/cargo/core/resolver/encode.rs
src/cargo/core/resolver/features.rs
src/cargo/core/resolver/resolve.rs
src/cargo/core/resolver/types.rs
src/cargo/core/summary.rs
src/cargo/core/workspace.rs
src/cargo/ops/cargo_clean.rs
src/cargo/ops/cargo_output_metadata.rs
src/cargo/ops/tree/graph.rs
src/cargo/sources/registry/index.rs
src/cargo/sources/registry/local.rs
src/cargo/sources/registry/mod.rs
src/cargo/sources/registry/remote.rs
src/cargo/util/command_prelude.rs
src/cargo/util/interning.rs [new file with mode: 0644]
src/cargo/util/mod.rs
src/cargo/util/rustc.rs
src/cargo/util/toml/mod.rs
tests/testsuite/config.rs
tests/testsuite/profile_config.rs

index a05c6e3b7a579f26f8930fe342e6888ef9bcfb24..d981c3604fcc27925a6f875e9dacd0f80e67167f 100644 (file)
@@ -1,5 +1,5 @@
 use crate::core::compiler::CompileKind;
-use crate::core::interning::InternedString;
+use crate::util::interning::InternedString;
 use crate::util::ProcessBuilder;
 use crate::util::{CargoResult, Config, RustfixDiagnosticServer};
 use anyhow::bail;
index ac7d6eca2959ee79da62fb08ecdeb20c6f5d785e..47efdc77de8ffd3094b7dace47bcb2cd7a2409b4 100644 (file)
@@ -2,9 +2,10 @@ use crate::core::compiler::unit_graph::UnitGraph;
 use crate::core::compiler::{BuildConfig, CompileKind, Unit};
 use crate::core::profiles::Profiles;
 use crate::core::PackageSet;
-use crate::core::{InternedString, Workspace};
+use crate::core::Workspace;
 use crate::util::config::Config;
 use crate::util::errors::CargoResult;
+use crate::util::interning::InternedString;
 use crate::util::Rustc;
 use std::collections::HashMap;
 use std::path::PathBuf;
index e2089d969bd121aa484cadf391efa2931999921d..a621d8ce7f7687fd51ac5dbcb71a8ead8d5a7d0f 100644 (file)
@@ -1,5 +1,6 @@
-use crate::core::{InternedString, Target};
+use crate::core::Target;
 use crate::util::errors::{CargoResult, CargoResultExt};
+use crate::util::interning::InternedString;
 use crate::util::Config;
 use anyhow::bail;
 use serde::Serialize;
index 4adab7efbcfbc961d77d7411aa2f7e4a5cf3b173..ded419acbae2ef0ab2faf44f83e9d59a2b73ccfa 100644 (file)
@@ -323,9 +323,10 @@ use serde::ser;
 use serde::{Deserialize, Serialize};
 
 use crate::core::compiler::unit_graph::UnitDep;
-use crate::core::{InternedString, Package};
+use crate::core::Package;
 use crate::util;
 use crate::util::errors::{CargoResult, CargoResultExt};
+use crate::util::interning::InternedString;
 use crate::util::paths;
 use crate::util::{internal, profile};
 
index 6d776e872150c5c8a6a36365aa4f4ba774d89d22..5c401e82a1d23d9853b3515f6adec2f7f5d9248b 100644 (file)
@@ -1,6 +1,6 @@
 use crate::core::compiler::{CompileMode, Context, CrateType, Unit};
-use crate::core::interning::InternedString;
 use crate::core::profiles;
+use crate::util::interning::InternedString;
 
 use crate::util::errors::CargoResult;
 use std::collections::hash_map::{Entry, HashMap};
index dd2a3c5da20c6a5b7f47e94682df270cdd30097d..fc9a897b2d1b5a6298bd0ae61ae5f51a7af42d02 100644 (file)
@@ -49,8 +49,9 @@ use self::unit_graph::UnitDep;
 pub use crate::core::compiler::unit::{Unit, UnitInterner};
 use crate::core::manifest::TargetSourcePath;
 use crate::core::profiles::{PanicStrategy, Profile, Strip};
-use crate::core::{Edition, Feature, InternedString, PackageId, Target};
+use crate::core::{Edition, Feature, PackageId, Target};
 use crate::util::errors::{self, CargoResult, CargoResultExt, ProcessError, VerboseError};
+use crate::util::interning::InternedString;
 use crate::util::machine_message::Message;
 use crate::util::{self, machine_message, ProcessBuilder};
 use crate::util::{internal, join_paths, paths, profile};
index a7f80321d410e8ae4adf690b104708dc8192d1cd..b4422f50474af21f9561f0d85eed20a484c95654 100644 (file)
@@ -1,7 +1,8 @@
 use crate::core::compiler::{CompileKind, CompileMode, CrateType};
 use crate::core::manifest::{Target, TargetKind};
-use crate::core::{profiles::Profile, InternedString, Package};
+use crate::core::{profiles::Profile, Package};
 use crate::util::hex::short_hash;
+use crate::util::interning::InternedString;
 use crate::util::Config;
 use std::cell::RefCell;
 use std::collections::HashSet;
index 542bc8c985d078c687f00e684130e4c92dfc6343..5bd8c0aff8735b2133639ff228e5253e3960791f 100644 (file)
@@ -22,8 +22,9 @@ use crate::core::dependency::DepKind;
 use crate::core::profiles::{Profile, Profiles, UnitFor};
 use crate::core::resolver::features::{FeaturesFor, ResolvedFeatures};
 use crate::core::resolver::Resolve;
-use crate::core::{InternedString, Package, PackageId, PackageSet, Target, Workspace};
+use crate::core::{Package, PackageId, PackageSet, Target, Workspace};
 use crate::ops::resolve_all_features;
+use crate::util::interning::InternedString;
 use crate::util::Config;
 use crate::CargoResult;
 use log::trace;
index d242f6b0497f67bd62bec0859cf89d726fe5a9c6..243a32a6ae2e198daffbf2b0715c608d81650c12 100644 (file)
@@ -1,7 +1,8 @@
 use crate::core::compiler::Unit;
 use crate::core::compiler::{CompileKind, CompileMode};
 use crate::core::profiles::{Profile, UnitFor};
-use crate::core::{nightly_features_allowed, InternedString, PackageId, Target};
+use crate::core::{nightly_features_allowed, PackageId, Target};
+use crate::util::interning::InternedString;
 use crate::util::CargoResult;
 use std::collections::HashMap;
 use std::io::Write;
index 4ca071447b8feffc86e7383b83a3fe7a0804ee78..2d586b5dfa12f48cf8a8ad9a4e6407c32c367a91 100644 (file)
@@ -6,9 +6,9 @@ use serde::ser;
 use serde::Serialize;
 use std::rc::Rc;
 
-use crate::core::interning::InternedString;
 use crate::core::{PackageId, SourceId, Summary};
 use crate::util::errors::{CargoResult, CargoResultExt};
+use crate::util::interning::InternedString;
 use crate::util::Config;
 
 /// Information about a dependency requested by a Cargo manifest.
diff --git a/src/cargo/core/interning.rs b/src/cargo/core/interning.rs
deleted file mode 100644 (file)
index 942869a..0000000
+++ /dev/null
@@ -1,182 +0,0 @@
-use serde::{Serialize, Serializer};
-use std::borrow::Borrow;
-use std::cmp::Ordering;
-use std::collections::HashSet;
-use std::ffi::OsStr;
-use std::fmt;
-use std::hash::{Hash, Hasher};
-use std::ops::Deref;
-use std::path::Path;
-use std::ptr;
-use std::str;
-use std::sync::Mutex;
-
-pub fn leak(s: String) -> &'static str {
-    Box::leak(s.into_boxed_str())
-}
-
-lazy_static::lazy_static! {
-    static ref STRING_CACHE: Mutex<HashSet<&'static str>> = Mutex::new(HashSet::new());
-}
-
-#[derive(Clone, Copy)]
-pub struct InternedString {
-    inner: &'static str,
-}
-
-impl<'a> From<&'a str> for InternedString {
-    fn from(item: &'a str) -> Self {
-        InternedString::new(item)
-    }
-}
-
-impl<'a> From<&'a String> for InternedString {
-    fn from(item: &'a String) -> Self {
-        InternedString::new(item)
-    }
-}
-
-impl From<String> for InternedString {
-    fn from(item: String) -> Self {
-        InternedString::new(&item)
-    }
-}
-
-impl PartialEq for InternedString {
-    fn eq(&self, other: &InternedString) -> bool {
-        ptr::eq(self.as_str(), other.as_str())
-    }
-}
-
-impl PartialEq<str> for InternedString {
-    fn eq(&self, other: &str) -> bool {
-        *self == other
-    }
-}
-
-impl<'a> PartialEq<&'a str> for InternedString {
-    fn eq(&self, other: &&str) -> bool {
-        **self == **other
-    }
-}
-
-impl Eq for InternedString {}
-
-impl InternedString {
-    pub fn new(str: &str) -> InternedString {
-        let mut cache = STRING_CACHE.lock().unwrap();
-        let s = cache.get(str).cloned().unwrap_or_else(|| {
-            let s = leak(str.to_string());
-            cache.insert(s);
-            s
-        });
-
-        InternedString { inner: s }
-    }
-
-    pub fn as_str(&self) -> &'static str {
-        self.inner
-    }
-}
-
-impl Deref for InternedString {
-    type Target = str;
-
-    fn deref(&self) -> &'static str {
-        self.as_str()
-    }
-}
-
-impl AsRef<str> for InternedString {
-    fn as_ref(&self) -> &str {
-        self.as_str()
-    }
-}
-
-impl AsRef<OsStr> for InternedString {
-    fn as_ref(&self) -> &OsStr {
-        self.as_str().as_ref()
-    }
-}
-
-impl AsRef<Path> for InternedString {
-    fn as_ref(&self) -> &Path {
-        self.as_str().as_ref()
-    }
-}
-
-impl Hash for InternedString {
-    // N.B., we can't implement this as `identity(self).hash(state)`,
-    // because we use this for on-disk fingerprints and so need
-    // stability across Cargo invocations.
-    fn hash<H: Hasher>(&self, state: &mut H) {
-        self.as_str().hash(state);
-    }
-}
-
-impl Borrow<str> for InternedString {
-    // If we implement Hash as `identity(self).hash(state)`,
-    // then this will need to be removed.
-    fn borrow(&self) -> &str {
-        self.as_str()
-    }
-}
-
-impl fmt::Debug for InternedString {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        fmt::Debug::fmt(self.as_str(), f)
-    }
-}
-
-impl fmt::Display for InternedString {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        fmt::Display::fmt(self.as_str(), f)
-    }
-}
-
-impl Ord for InternedString {
-    fn cmp(&self, other: &InternedString) -> Ordering {
-        self.as_str().cmp(other.as_str())
-    }
-}
-
-impl PartialOrd for InternedString {
-    fn partial_cmp(&self, other: &InternedString) -> Option<Ordering> {
-        Some(self.cmp(other))
-    }
-}
-
-impl Serialize for InternedString {
-    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
-    where
-        S: Serializer,
-    {
-        serializer.serialize_str(self.inner)
-    }
-}
-
-struct InternedStringVisitor;
-
-impl<'de> serde::Deserialize<'de> for InternedString {
-    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
-    where
-        D: serde::Deserializer<'de>,
-    {
-        deserializer.deserialize_str(InternedStringVisitor)
-    }
-}
-
-impl<'de> serde::de::Visitor<'de> for InternedStringVisitor {
-    type Value = InternedString;
-
-    fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
-        formatter.write_str("an String like thing")
-    }
-
-    fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
-    where
-        E: serde::de::Error,
-    {
-        Ok(InternedString::new(v))
-    }
-}
index 6978081a6fa4f5256b785fd29ea0d7b656528a9c..008cec3b79c4f59bf3276fe77c98dc9eb8f68b24 100644 (file)
@@ -11,11 +11,11 @@ use serde::Serialize;
 use url::Url;
 
 use crate::core::compiler::CrateType;
-use crate::core::interning::InternedString;
 use crate::core::resolver::ResolveBehavior;
 use crate::core::{Dependency, PackageId, PackageIdSpec, SourceId, Summary};
 use crate::core::{Edition, Feature, Features, WorkspaceConfig};
 use crate::util::errors::*;
+use crate::util::interning::InternedString;
 use crate::util::toml::{TomlManifest, TomlProfiles};
 use crate::util::{short_hash, Config, Filesystem};
 
index 3d664d153b7b2c9ae7681f438e4053c3f28145ef..5abab1b9cd45b8c9c7f88bcca859a1034badde03 100644 (file)
@@ -3,7 +3,6 @@ pub use self::features::{
     enable_nightly_features, maybe_allow_nightly_features, nightly_features_allowed,
 };
 pub use self::features::{CliUnstable, Edition, Feature, Features};
-pub use self::interning::InternedString;
 pub use self::manifest::{EitherManifest, VirtualManifest};
 pub use self::manifest::{Manifest, Target, TargetKind};
 pub use self::package::{Package, PackageSet};
@@ -19,7 +18,6 @@ pub use self::workspace::{Members, Workspace, WorkspaceConfig, WorkspaceRootConf
 pub mod compiler;
 pub mod dependency;
 pub mod features;
-mod interning;
 pub mod manifest;
 pub mod package;
 pub mod package_id;
index 8acb87097de652f1db09723b207343f211cea3eb..1187def1db41df22e7a16a2af9bb90c65080a1be 100644 (file)
@@ -20,7 +20,6 @@ use serde::Serialize;
 
 use crate::core::compiler::{CompileKind, RustcTargetData};
 use crate::core::dependency::DepKind;
-use crate::core::interning::InternedString;
 use crate::core::resolver::{HasDevUnits, Resolve};
 use crate::core::source::MaybePackage;
 use crate::core::{Dependency, Manifest, PackageId, SourceId, Target};
@@ -28,6 +27,7 @@ use crate::core::{FeatureMap, SourceMap, Summary, Workspace};
 use crate::ops;
 use crate::util::config::PackageCacheLock;
 use crate::util::errors::{CargoResult, CargoResultExt, HttpNot200};
+use crate::util::interning::InternedString;
 use crate::util::network::Retry;
 use crate::util::{self, internal, Config, Progress, ProgressStyle};
 
index 088a4d98d796da31a26e1a88ea94a100af91ba54..5764f97c776dd7bb9f2a623ed8dcd65448b261ea 100644 (file)
@@ -9,8 +9,8 @@ use std::sync::Mutex;
 use serde::de;
 use serde::ser;
 
-use crate::core::interning::InternedString;
 use crate::core::source::SourceId;
+use crate::util::interning::InternedString;
 use crate::util::{CargoResult, ToSemver};
 
 lazy_static::lazy_static! {
index ff70bfae3b1ac69186dba9e50e72ca7191415f86..57a2db614361ddca1e7d1593a59e323e4d5eec0b 100644 (file)
@@ -5,9 +5,9 @@ use semver::Version;
 use serde::{de, ser};
 use url::Url;
 
-use crate::core::interning::InternedString;
 use crate::core::PackageId;
 use crate::util::errors::{CargoResult, CargoResultExt};
+use crate::util::interning::InternedString;
 use crate::util::{validate_package_name, IntoUrl, ToSemver};
 
 /// Some or all of the data required to identify a package:
@@ -274,8 +274,8 @@ impl<'de> de::Deserialize<'de> for PackageIdSpec {
 #[cfg(test)]
 mod tests {
     use super::PackageIdSpec;
-    use crate::core::interning::InternedString;
     use crate::core::{PackageId, SourceId};
+    use crate::util::interning::InternedString;
     use crate::util::ToSemver;
     use url::Url;
 
index 7d97576c2da027fd992c0d0d0ea2f56fd791d07b..6a28bd2610ff3dc6b7957f3c9b97d310b0d992f3 100644 (file)
@@ -1,8 +1,8 @@
 use crate::core::compiler::CompileMode;
-use crate::core::interning::InternedString;
 use crate::core::resolver::features::FeaturesFor;
 use crate::core::{Feature, Features, PackageId, PackageIdSpec, Resolve, Shell};
 use crate::util::errors::CargoResultExt;
+use crate::util::interning::InternedString;
 use crate::util::toml::{ProfilePackageSpec, StringOrBool, TomlProfile, TomlProfiles, U32OrBool};
 use crate::util::{closest_msg, config, CargoResult, Config};
 use anyhow::bail;
index 160ca770ad71f0cea6f320d1a4a1a9ab95d72e60..d8b784d1db081ddf4b35653bc0699f8e1c802d63 100644 (file)
@@ -5,10 +5,11 @@ use log::{debug, trace};
 use semver::VersionReq;
 use url::Url;
 
+use crate::core::PackageSet;
 use crate::core::{Dependency, PackageId, Source, SourceId, SourceMap, Summary};
-use crate::core::{InternedString, PackageSet};
 use crate::sources::config::SourceConfigMap;
 use crate::util::errors::{CargoResult, CargoResultExt};
+use crate::util::interning::InternedString;
 use crate::util::{profile, CanonicalUrl, Config};
 
 /// Source of information about a group of packages.
index 7924f8cb07fd00e54b9aa42aabde1bd3a498701b..95f4a9fe663d62215e3bcd6ed89240578ab275c0 100644 (file)
@@ -4,8 +4,8 @@ use std::num::NonZeroU64;
 use anyhow::format_err;
 use log::debug;
 
-use crate::core::interning::InternedString;
 use crate::core::{Dependency, PackageId, SourceId, Summary};
+use crate::util::interning::InternedString;
 use crate::util::Graph;
 
 use super::dep_cache::RegistryQueryer;
index c23629d715734f210094e29e0306a5c17325478c..b9d681fd401d445733ff928789b56710d466561b 100644 (file)
@@ -15,11 +15,11 @@ use std::rc::Rc;
 
 use log::debug;
 
-use crate::core::interning::InternedString;
 use crate::core::resolver::context::Context;
 use crate::core::resolver::errors::describe_path;
 use crate::core::{Dependency, FeatureValue, PackageId, PackageIdSpec, Registry, Summary};
 use crate::util::errors::{CargoResult, CargoResultExt};
+use crate::util::interning::InternedString;
 
 use crate::core::resolver::types::{ConflictReason, DepInfo, FeaturesSet};
 use crate::core::resolver::{ActivateResult, ResolveOpts};
index 4d71149823592c53371b9c22ce13205d9d538d26..7b30c470a6b80da7c23e7a1b42be3da195c1f7fb 100644 (file)
@@ -98,9 +98,9 @@ use serde::de;
 use serde::ser;
 use serde::{Deserialize, Serialize};
 
-use crate::core::InternedString;
 use crate::core::{Dependency, Package, PackageId, SourceId, Workspace};
 use crate::util::errors::{CargoResult, CargoResultExt};
+use crate::util::interning::InternedString;
 use crate::util::{internal, Graph};
 
 use super::{Resolve, ResolveVersion};
index a2c25cb95c6314219a6da3e3296eb74c2d36b092..026f0af51f33e42112627fb60d043aa9ea49951f 100644 (file)
@@ -42,7 +42,8 @@ use crate::core::compiler::{CompileKind, RustcTargetData};
 use crate::core::dependency::{DepKind, Dependency};
 use crate::core::resolver::types::FeaturesSet;
 use crate::core::resolver::{Resolve, ResolveBehavior};
-use crate::core::{FeatureValue, InternedString, PackageId, PackageIdSpec, PackageSet, Workspace};
+use crate::core::{FeatureValue, PackageId, PackageIdSpec, PackageSet, Workspace};
+use crate::util::interning::InternedString;
 use crate::util::CargoResult;
 use std::collections::{BTreeSet, HashMap, HashSet};
 use std::rc::Rc;
index 80904299f79992d3a1e79b0f770da1305f509a22..c0bb53c7d9f3c69a92e57accbfa380ab6ff69339 100644 (file)
@@ -1,8 +1,8 @@
 use super::encode::Metadata;
 use crate::core::dependency::DepKind;
-use crate::core::interning::InternedString;
 use crate::core::{Dependency, PackageId, PackageIdSpec, Summary, Target};
 use crate::util::errors::CargoResult;
+use crate::util::interning::InternedString;
 use crate::util::Graph;
 use std::borrow::Borrow;
 use std::cmp;
index ab988a8523e19f1f7b5035f00fc835e018363852..dabe8c094e1224a86c9b9ac2d4776f142af7c2f3 100644 (file)
@@ -1,7 +1,7 @@
 use super::features::RequestedFeatures;
-use crate::core::interning::InternedString;
 use crate::core::{Dependency, PackageId, Summary};
 use crate::util::errors::CargoResult;
+use crate::util::interning::InternedString;
 use crate::util::Config;
 use std::cmp::Ordering;
 use std::collections::{BTreeMap, BTreeSet};
index 0efdc477fe27ebb3aa719b38ffe541fff29d955e..70774577a8a8092d5f9f5aa04f45993c09a8c308 100644 (file)
@@ -7,8 +7,8 @@ use std::rc::Rc;
 
 use serde::{Serialize, Serializer};
 
-use crate::core::interning::InternedString;
 use crate::core::{Dependency, PackageId, SourceId};
+use crate::util::interning::InternedString;
 use semver::Version;
 
 use crate::util::CargoResult;
index db4b655c46445e99b98e3edc84f35c23c2b82ebb..ccde5b9eccea599dace70619cf7c0186631a722a 100644 (file)
@@ -13,11 +13,12 @@ use crate::core::features::Features;
 use crate::core::registry::PackageRegistry;
 use crate::core::resolver::features::RequestedFeatures;
 use crate::core::resolver::ResolveBehavior;
-use crate::core::{Dependency, InternedString, PackageId, PackageIdSpec};
+use crate::core::{Dependency, PackageId, PackageIdSpec};
 use crate::core::{EitherManifest, Package, SourceId, VirtualManifest};
 use crate::ops;
 use crate::sources::PathSource;
 use crate::util::errors::{CargoResult, CargoResultExt, ManifestError};
+use crate::util::interning::InternedString;
 use crate::util::paths;
 use crate::util::toml::{read_manifest, TomlProfiles};
 use crate::util::{Config, Filesystem};
index d4bc8ce52953c27e029e858ce7f250e59b99dba5..5efa976f04dd1a52da379f650b78a53f4f8196f3 100644 (file)
@@ -1,8 +1,9 @@
 use crate::core::compiler::{CompileKind, CompileMode, Layout, RustcTargetData};
 use crate::core::profiles::Profiles;
-use crate::core::{InternedString, PackageIdSpec, TargetKind, Workspace};
+use crate::core::{PackageIdSpec, TargetKind, Workspace};
 use crate::ops;
 use crate::util::errors::{CargoResult, CargoResultExt};
+use crate::util::interning::InternedString;
 use crate::util::paths;
 use crate::util::Config;
 use std::fs;
index 56def0312470f68b21cb1f352db7ea454dd0e70e..d4ea0fde70e4b4bc213c5ed3f16736868f38e60b 100644 (file)
@@ -1,8 +1,9 @@
 use crate::core::compiler::{CompileKind, RustcTargetData};
 use crate::core::dependency::DepKind;
 use crate::core::resolver::{HasDevUnits, Resolve, ResolveOpts};
-use crate::core::{Dependency, InternedString, Package, PackageId, Workspace};
+use crate::core::{Dependency, Package, PackageId, Workspace};
 use crate::ops::{self, Packages};
+use crate::util::interning::InternedString;
 use crate::util::CargoResult;
 use cargo_platform::Platform;
 use serde::Serialize;
index 5698cf04bebbe3102e9ba5dd82ed866c69ef4e8a..363199a218b8d3555fc9a398a232adf05bff8a74 100644 (file)
@@ -5,9 +5,8 @@ use crate::core::compiler::{CompileKind, RustcTargetData};
 use crate::core::dependency::DepKind;
 use crate::core::resolver::features::{FeaturesFor, RequestedFeatures, ResolvedFeatures};
 use crate::core::resolver::Resolve;
-use crate::core::{
-    FeatureMap, FeatureValue, InternedString, Package, PackageId, PackageIdSpec, Workspace,
-};
+use crate::core::{FeatureMap, FeatureValue, Package, PackageId, PackageIdSpec, Workspace};
+use crate::util::interning::InternedString;
 use crate::util::CargoResult;
 use std::collections::{HashMap, HashSet};
 
index 9743ccfe3496f9b48ea68ef20ca984fc2bc52c5f..3b9a16d654283fb78b7dc37ac92a281b31b1e971 100644 (file)
@@ -67,8 +67,9 @@
 //! hopefully those are more obvious inline in the code itself.
 
 use crate::core::dependency::Dependency;
-use crate::core::{InternedString, PackageId, SourceId, Summary};
+use crate::core::{PackageId, SourceId, Summary};
 use crate::sources::registry::{RegistryData, RegistryPackage};
+use crate::util::interning::InternedString;
 use crate::util::paths;
 use crate::util::{internal, CargoResult, Config, Filesystem, ToSemver};
 use log::info;
index d9c1221b04ca045442240af76ed3e3e36a95cae7..d35345eb86c7b221e514fcdd247eeb27f17fe9ba 100644 (file)
@@ -1,6 +1,7 @@
-use crate::core::{InternedString, PackageId};
+use crate::core::PackageId;
 use crate::sources::registry::{MaybeLock, RegistryConfig, RegistryData};
 use crate::util::errors::CargoResult;
+use crate::util::interning::InternedString;
 use crate::util::paths;
 use crate::util::{Config, Filesystem, Sha256};
 use std::fs::File;
index 44328b29fbdd61390c46383602a0a242a4aeeb8e..c9ab7ff4ecdf9e62ee4c3cb10bcdcccb78512f0c 100644 (file)
@@ -173,10 +173,11 @@ use tar::Archive;
 
 use crate::core::dependency::{DepKind, Dependency};
 use crate::core::source::MaybePackage;
-use crate::core::{InternedString, Package, PackageId, Source, SourceId, Summary};
+use crate::core::{Package, PackageId, Source, SourceId, Summary};
 use crate::sources::PathSource;
 use crate::util::errors::CargoResultExt;
 use crate::util::hex;
+use crate::util::interning::InternedString;
 use crate::util::into_url::IntoUrl;
 use crate::util::{restricted_names, CargoResult, Config, Filesystem};
 
index 9c610ae82abbc25f453c2845b8ed78960fef52cc..a96c2bbf258e201386e3632df9dba8351e4760ab 100644 (file)
@@ -1,4 +1,4 @@
-use crate::core::{GitReference, InternedString, PackageId, SourceId};
+use crate::core::{GitReference, PackageId, SourceId};
 use crate::sources::git;
 use crate::sources::registry::MaybeLock;
 use crate::sources::registry::{
@@ -6,6 +6,7 @@ use crate::sources::registry::{
     VERSION_TEMPLATE,
 };
 use crate::util::errors::{CargoResult, CargoResultExt};
+use crate::util::interning::InternedString;
 use crate::util::paths;
 use crate::util::{Config, Filesystem, Sha256};
 use lazycell::LazyCell;
index 60df3de3bfe6fc1ff2a2e088de53e362048ea91e..a0b2e0ed6bec9ce7832e8b7900c5216dd681ea04 100644 (file)
@@ -1,9 +1,9 @@
 use crate::core::compiler::{BuildConfig, MessageFormat};
-use crate::core::InternedString;
 use crate::core::Workspace;
 use crate::ops::{CompileFilter, CompileOptions, NewOptions, Packages, VersionControl};
 use crate::sources::CRATES_IO_REGISTRY;
 use crate::util::important_paths::find_root_manifest_for_wd;
+use crate::util::interning::InternedString;
 use crate::util::{paths, toml::TomlProfile, validate_package_name};
 use crate::util::{
     print_available_benches, print_available_binaries, print_available_examples,
diff --git a/src/cargo/util/interning.rs b/src/cargo/util/interning.rs
new file mode 100644 (file)
index 0000000..942869a
--- /dev/null
@@ -0,0 +1,182 @@
+use serde::{Serialize, Serializer};
+use std::borrow::Borrow;
+use std::cmp::Ordering;
+use std::collections::HashSet;
+use std::ffi::OsStr;
+use std::fmt;
+use std::hash::{Hash, Hasher};
+use std::ops::Deref;
+use std::path::Path;
+use std::ptr;
+use std::str;
+use std::sync::Mutex;
+
+pub fn leak(s: String) -> &'static str {
+    Box::leak(s.into_boxed_str())
+}
+
+lazy_static::lazy_static! {
+    static ref STRING_CACHE: Mutex<HashSet<&'static str>> = Mutex::new(HashSet::new());
+}
+
+#[derive(Clone, Copy)]
+pub struct InternedString {
+    inner: &'static str,
+}
+
+impl<'a> From<&'a str> for InternedString {
+    fn from(item: &'a str) -> Self {
+        InternedString::new(item)
+    }
+}
+
+impl<'a> From<&'a String> for InternedString {
+    fn from(item: &'a String) -> Self {
+        InternedString::new(item)
+    }
+}
+
+impl From<String> for InternedString {
+    fn from(item: String) -> Self {
+        InternedString::new(&item)
+    }
+}
+
+impl PartialEq for InternedString {
+    fn eq(&self, other: &InternedString) -> bool {
+        ptr::eq(self.as_str(), other.as_str())
+    }
+}
+
+impl PartialEq<str> for InternedString {
+    fn eq(&self, other: &str) -> bool {
+        *self == other
+    }
+}
+
+impl<'a> PartialEq<&'a str> for InternedString {
+    fn eq(&self, other: &&str) -> bool {
+        **self == **other
+    }
+}
+
+impl Eq for InternedString {}
+
+impl InternedString {
+    pub fn new(str: &str) -> InternedString {
+        let mut cache = STRING_CACHE.lock().unwrap();
+        let s = cache.get(str).cloned().unwrap_or_else(|| {
+            let s = leak(str.to_string());
+            cache.insert(s);
+            s
+        });
+
+        InternedString { inner: s }
+    }
+
+    pub fn as_str(&self) -> &'static str {
+        self.inner
+    }
+}
+
+impl Deref for InternedString {
+    type Target = str;
+
+    fn deref(&self) -> &'static str {
+        self.as_str()
+    }
+}
+
+impl AsRef<str> for InternedString {
+    fn as_ref(&self) -> &str {
+        self.as_str()
+    }
+}
+
+impl AsRef<OsStr> for InternedString {
+    fn as_ref(&self) -> &OsStr {
+        self.as_str().as_ref()
+    }
+}
+
+impl AsRef<Path> for InternedString {
+    fn as_ref(&self) -> &Path {
+        self.as_str().as_ref()
+    }
+}
+
+impl Hash for InternedString {
+    // N.B., we can't implement this as `identity(self).hash(state)`,
+    // because we use this for on-disk fingerprints and so need
+    // stability across Cargo invocations.
+    fn hash<H: Hasher>(&self, state: &mut H) {
+        self.as_str().hash(state);
+    }
+}
+
+impl Borrow<str> for InternedString {
+    // If we implement Hash as `identity(self).hash(state)`,
+    // then this will need to be removed.
+    fn borrow(&self) -> &str {
+        self.as_str()
+    }
+}
+
+impl fmt::Debug for InternedString {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        fmt::Debug::fmt(self.as_str(), f)
+    }
+}
+
+impl fmt::Display for InternedString {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        fmt::Display::fmt(self.as_str(), f)
+    }
+}
+
+impl Ord for InternedString {
+    fn cmp(&self, other: &InternedString) -> Ordering {
+        self.as_str().cmp(other.as_str())
+    }
+}
+
+impl PartialOrd for InternedString {
+    fn partial_cmp(&self, other: &InternedString) -> Option<Ordering> {
+        Some(self.cmp(other))
+    }
+}
+
+impl Serialize for InternedString {
+    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+    where
+        S: Serializer,
+    {
+        serializer.serialize_str(self.inner)
+    }
+}
+
+struct InternedStringVisitor;
+
+impl<'de> serde::Deserialize<'de> for InternedString {
+    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+    where
+        D: serde::Deserializer<'de>,
+    {
+        deserializer.deserialize_str(InternedStringVisitor)
+    }
+}
+
+impl<'de> serde::de::Visitor<'de> for InternedStringVisitor {
+    type Value = InternedString;
+
+    fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
+        formatter.write_str("an String like thing")
+    }
+
+    fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
+    where
+        E: serde::de::Error,
+    {
+        Ok(InternedString::new(v))
+    }
+}
index 7f2ba2697e4d9dedd2eb41b17a96c3ce6f027191..8bed0b9163348752b1be82f2ce0de2278f39a4ba 100644 (file)
@@ -43,6 +43,7 @@ pub mod graph;
 mod hasher;
 pub mod hex;
 pub mod important_paths;
+pub mod interning;
 pub mod into_url;
 mod into_url_with_base;
 pub mod job;
index 2ab08fec6ccfca9aa09d29a997ddaf155a1e6f4b..aa71381856302c80ef1f5275ff5936e01a84e741 100644 (file)
@@ -7,7 +7,7 @@ use std::sync::Mutex;
 use log::{debug, info, warn};
 use serde::{Deserialize, Serialize};
 
-use crate::core::InternedString;
+use crate::util::interning::InternedString;
 use crate::util::paths;
 use crate::util::{self, profile, CargoResult, CargoResultExt, ProcessBuilder, StableHasher};
 
index e01052b666b876cd231aac06485c9519de4d7bd7..6dc4a409801401116b4231eea864b4ad24a4ce00 100644 (file)
@@ -17,11 +17,12 @@ use crate::core::dependency::DepKind;
 use crate::core::manifest::{ManifestMetadata, TargetSourcePath, Warnings};
 use crate::core::profiles::Strip;
 use crate::core::resolver::ResolveBehavior;
-use crate::core::{Dependency, InternedString, Manifest, PackageId, Summary, Target};
+use crate::core::{Dependency, Manifest, PackageId, Summary, Target};
 use crate::core::{Edition, EitherManifest, Feature, Features, VirtualManifest, Workspace};
 use crate::core::{GitReference, PackageIdSpec, SourceId, WorkspaceConfig, WorkspaceRootConfig};
 use crate::sources::{CRATES_IO_INDEX, CRATES_IO_REGISTRY};
 use crate::util::errors::{CargoResult, CargoResultExt, ManifestError};
+use crate::util::interning::InternedString;
 use crate::util::{self, paths, validate_package_name, Config, IntoUrl};
 
 mod targets;
index 4cbea32f54ae08503cf62f6a62b5459fda4e16d0..5771440e9da90c191585f24f9553efc8641410c5 100644 (file)
@@ -1,7 +1,8 @@
 //! Tests for config settings.
 
-use cargo::core::{enable_nightly_features, InternedString, Shell};
+use cargo::core::{enable_nightly_features, Shell};
 use cargo::util::config::{self, Config, SslVersionConfig, StringList};
+use cargo::util::interning::InternedString;
 use cargo::util::toml::{self, VecStringOrBool as VSOB};
 use cargo::CargoResult;
 use cargo_test_support::{normalized_lines_match, paths, project, t};
index 12d0693a07645f8c3b0737e46fb50cef224fde60..a1dc5c35b191d74f0ec991d5be313454a46e2a5c 100644 (file)
@@ -346,7 +346,8 @@ fn named_config_profile() {
     use cargo::core::enable_nightly_features;
     use cargo::core::features::Features;
     use cargo::core::profiles::{Profiles, UnitFor};
-    use cargo::core::{InternedString, PackageId};
+    use cargo::core::PackageId;
+    use cargo::util::interning::InternedString;
     use cargo::util::toml::TomlProfiles;
     use std::fs;
     enable_nightly_features();