From 43505bf56c3de15638d4d6e0e5af0bed69d5d3b5 Mon Sep 17 00:00:00 2001 From: klensy Date: Sun, 16 Feb 2025 16:37:12 +0300 Subject: [PATCH 1/2] use triomphe::Arc for InternedObligationCauseCode --- Cargo.lock | 13 +++++++ Cargo.toml | 3 ++ compiler/rustc_data_structures/Cargo.toml | 1 + compiler/rustc_data_structures/src/marker.rs | 2 + .../src/stable_hasher.rs | 7 ++++ compiler/rustc_middle/Cargo.toml | 1 + compiler/rustc_middle/src/traits/mod.rs | 11 ++++-- compiler/rustc_serialize/Cargo.toml | 1 + compiler/rustc_serialize/src/serialize.rs | 13 +++++++ compiler/rustc_type_ir/Cargo.toml | 1 + compiler/rustc_type_ir/src/fold.rs | 38 +++++++++++++++++++ compiler/rustc_type_ir/src/visit.rs | 6 +++ 12 files changed, 93 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 38a861727a9d3..347cd57a07762 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3666,6 +3666,7 @@ dependencies = [ "tempfile", "thin-vec", "tracing", + "triomphe", "windows 0.59.0", ] @@ -4183,6 +4184,7 @@ dependencies = [ "smallvec", "thin-vec", "tracing", + "triomphe", ] [[package]] @@ -4492,6 +4494,7 @@ dependencies = [ "smallvec", "tempfile", "thin-vec", + "triomphe", ] [[package]] @@ -4694,6 +4697,7 @@ dependencies = [ "smallvec", "thin-vec", "tracing", + "triomphe", ] [[package]] @@ -5630,6 +5634,15 @@ dependencies = [ "tracing-subscriber", ] +[[package]] +name = "triomphe" +version = "0.1.14" +source = "git+https://github.com/Manishearth/triomphe.git?rev=6ff0527036632be33a6ed45e5e8a0fb6243dee47#6ff0527036632be33a6ed45e5e8a0fb6243dee47" +dependencies = [ + "serde", + "stable_deref_trait", +] + [[package]] name = "twox-hash" version = "1.6.3" diff --git a/Cargo.toml b/Cargo.toml index 97e782d0df020..4f6e6e13f711d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -93,3 +93,6 @@ codegen-units = 1 # FIXME: LTO cannot be enabled for binaries in a workspace # # lto = true + +[patch.crates-io] +triomphe = { git = 'https://github.com/Manishearth/triomphe.git', rev = '6ff0527036632be33a6ed45e5e8a0fb6243dee47' } diff --git a/compiler/rustc_data_structures/Cargo.toml b/compiler/rustc_data_structures/Cargo.toml index a8f83ca13e267..917f82fc853c0 100644 --- a/compiler/rustc_data_structures/Cargo.toml +++ b/compiler/rustc_data_structures/Cargo.toml @@ -26,6 +26,7 @@ stacker = "0.1.17" tempfile = "3.2" thin-vec = "0.2.12" tracing = "0.1" +triomphe = { version = "0.1.14", features = ["unstable_dropck_eyepatch"] } # tidy-alphabetical-end [dependencies.parking_lot] diff --git a/compiler/rustc_data_structures/src/marker.rs b/compiler/rustc_data_structures/src/marker.rs index 6ae97222f77fd..2a667da1deb28 100644 --- a/compiler/rustc_data_structures/src/marker.rs +++ b/compiler/rustc_data_structures/src/marker.rs @@ -65,6 +65,7 @@ impl_dyn_send!( [std::sync::Mutex where T: ?Sized+ DynSend] [std::sync::mpsc::Sender where T: DynSend] [std::sync::Arc where T: ?Sized + DynSync + DynSend] + [triomphe::Arc where T: ?Sized + DynSync + DynSend] [std::sync::LazyLock where T: DynSend, F: DynSend] [std::collections::HashSet where K: DynSend, S: DynSend] [std::collections::HashMap where K: DynSend, V: DynSend, S: DynSend] @@ -139,6 +140,7 @@ impl_dyn_sync!( [std::sync::OnceLock where T: DynSend + DynSync] [std::sync::Mutex where T: ?Sized + DynSend] [std::sync::Arc where T: ?Sized + DynSync + DynSend] + [triomphe::Arc where T: ?Sized + DynSync + DynSend] [std::sync::LazyLock where T: DynSend + DynSync, F: DynSend] [std::collections::HashSet where K: DynSync, S: DynSync] [std::collections::HashMap where K: DynSync, V: DynSync, S: DynSync] diff --git a/compiler/rustc_data_structures/src/stable_hasher.rs b/compiler/rustc_data_structures/src/stable_hasher.rs index 9cd0cc499ca32..7aeb083ceb0ff 100644 --- a/compiler/rustc_data_structures/src/stable_hasher.rs +++ b/compiler/rustc_data_structures/src/stable_hasher.rs @@ -395,6 +395,13 @@ impl, CTX> HashStable for ::std::sync::Arc { } } +impl, CTX> HashStable for ::triomphe::Arc { + #[inline] + fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { + (**self).hash_stable(ctx, hasher); + } +} + impl HashStable for str { #[inline] fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { diff --git a/compiler/rustc_middle/Cargo.toml b/compiler/rustc_middle/Cargo.toml index de722e62043cd..4fd011ba51aef 100644 --- a/compiler/rustc_middle/Cargo.toml +++ b/compiler/rustc_middle/Cargo.toml @@ -36,6 +36,7 @@ rustc_type_ir = { path = "../rustc_type_ir" } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } thin-vec = "0.2.12" tracing = "0.1" +triomphe = "0.1.14" # tidy-alphabetical-end [features] diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index f039da772fd4d..33a790c2fd18d 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -10,10 +10,8 @@ mod structural_impls; use std::borrow::Cow; use std::hash::{Hash, Hasher}; -use std::sync::Arc; use rustc_errors::{Applicability, Diag, EmissionGuarantee}; -use rustc_hir as hir; use rustc_hir::HirId; use rustc_hir::def_id::DefId; use rustc_macros::{ @@ -23,6 +21,7 @@ use rustc_span::def_id::{CRATE_DEF_ID, LocalDefId}; use rustc_span::{DUMMY_SP, Span, Symbol}; use smallvec::{SmallVec, smallvec}; use thin_vec::ThinVec; +use {rustc_hir as hir, triomphe}; pub use self::select::{EvaluationCache, EvaluationResult, OverflowError, SelectionCache}; use crate::mir::ConstraintCategory; @@ -157,7 +156,7 @@ pub struct UnifyReceiverContext<'tcx> { pub struct InternedObligationCauseCode<'tcx> { /// `None` for `ObligationCauseCode::Misc` (a common case, occurs ~60% of /// the time). `Some` otherwise. - code: Option>>, + code: Option>>, } impl<'tcx> std::fmt::Debug for InternedObligationCauseCode<'tcx> { @@ -171,7 +170,11 @@ impl<'tcx> ObligationCauseCode<'tcx> { #[inline(always)] fn into(self) -> InternedObligationCauseCode<'tcx> { InternedObligationCauseCode { - code: if let ObligationCauseCode::Misc = self { None } else { Some(Arc::new(self)) }, + code: if let ObligationCauseCode::Misc = self { + None + } else { + Some(triomphe::Arc::new(self)) + }, } } } diff --git a/compiler/rustc_serialize/Cargo.toml b/compiler/rustc_serialize/Cargo.toml index 8bf98c16361eb..8809239c3e62f 100644 --- a/compiler/rustc_serialize/Cargo.toml +++ b/compiler/rustc_serialize/Cargo.toml @@ -8,6 +8,7 @@ edition = "2021" indexmap = "2.0.0" smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } thin-vec = "0.2.12" +triomphe = "0.1.14" # tidy-alphabetical-end [dev-dependencies] diff --git a/compiler/rustc_serialize/src/serialize.rs b/compiler/rustc_serialize/src/serialize.rs index db8555edd0f8f..b5169fdce6d4f 100644 --- a/compiler/rustc_serialize/src/serialize.rs +++ b/compiler/rustc_serialize/src/serialize.rs @@ -12,6 +12,7 @@ use std::sync::Arc; use smallvec::{Array, SmallVec}; use thin_vec::ThinVec; +use triomphe; /// A byte that [cannot occur in UTF8 sequences][utf8]. Used to mark the end of a string. /// This way we can skip validation and still be relatively sure that deserialization @@ -486,6 +487,18 @@ impl> Decodable for Arc { } } +impl> Encodable for triomphe::Arc { + fn encode(&self, s: &mut S) { + (**self).encode(s); + } +} + +impl> Decodable for triomphe::Arc { + fn decode(d: &mut D) -> triomphe::Arc { + triomphe::Arc::new(Decodable::decode(d)) + } +} + impl> Encodable for Box { fn encode(&self, s: &mut S) { (**self).encode(s) diff --git a/compiler/rustc_type_ir/Cargo.toml b/compiler/rustc_type_ir/Cargo.toml index 8d97ec728304e..85aa52cf051ac 100644 --- a/compiler/rustc_type_ir/Cargo.toml +++ b/compiler/rustc_type_ir/Cargo.toml @@ -19,6 +19,7 @@ rustc_type_ir_macros = { path = "../rustc_type_ir_macros" } smallvec = { version = "1.8.1", default-features = false } thin-vec = "0.2.12" tracing = "0.1" +triomphe = "0.1.14" # tidy-alphabetical-end [features] diff --git a/compiler/rustc_type_ir/src/fold.rs b/compiler/rustc_type_ir/src/fold.rs index 0bc8b94bbf4cc..263dfd0501d9e 100644 --- a/compiler/rustc_type_ir/src/fold.rs +++ b/compiler/rustc_type_ir/src/fold.rs @@ -51,6 +51,7 @@ use std::sync::Arc; use rustc_index::{Idx, IndexVec}; use thin_vec::ThinVec; use tracing::{debug, instrument}; +use triomphe; use crate::inherent::*; use crate::visit::{TypeVisitable, TypeVisitableExt as _}; @@ -310,6 +311,43 @@ impl> TypeFoldable for Arc { } } +impl> TypeFoldable for triomphe::Arc { + fn try_fold_with>(mut self, folder: &mut F) -> Result { + // We merely want to replace the contained `T`, if at all possible, + // so that we don't needlessly allocate a new `Arc` or indeed clone + // the contained type. + unsafe { + // First step is to ensure that we have a unique reference to + // the contained type, which `Arc::make_mut` will accomplish (by + // allocating a new `Arc` and cloning the `T` only if required). + // This is done *before* casting to `Arc>` so that + // panicking during `make_mut` does not leak the `T`. + triomphe::Arc::make_mut(&mut self); + + // Casting to `Arc>` is safe because `ManuallyDrop` + // is `repr(transparent)`. + let ptr = triomphe::Arc::into_raw(self).cast::>(); + let mut unique = triomphe::Arc::from_raw(ptr); + + // Call to `Arc::make_mut` above guarantees that `unique` is the + // sole reference to the contained value, so we can avoid doing + // a checked `get_mut` here. + let slot = triomphe::Arc::get_mut(&mut unique).unwrap_unchecked(); + + // Semantically move the contained type out from `unique`, fold + // it, then move the folded value back into `unique`. Should + // folding fail, `ManuallyDrop` ensures that the "moved-out" + // value is not re-dropped. + let owned = mem::ManuallyDrop::take(slot); + let folded = owned.try_fold_with(folder)?; + *slot = mem::ManuallyDrop::new(folded); + + // Cast back to `Arc`. + Ok(triomphe::Arc::from_raw(triomphe::Arc::into_raw(unique).cast())) + } + } +} + impl> TypeFoldable for Box { fn try_fold_with>(mut self, folder: &mut F) -> Result { *self = (*self).try_fold_with(folder)?; diff --git a/compiler/rustc_type_ir/src/visit.rs b/compiler/rustc_type_ir/src/visit.rs index a12e9856304a9..4a01c55e5b165 100644 --- a/compiler/rustc_type_ir/src/visit.rs +++ b/compiler/rustc_type_ir/src/visit.rs @@ -173,6 +173,12 @@ impl> TypeVisitable for Arc { } } +impl> TypeVisitable for triomphe::Arc { + fn visit_with>(&self, visitor: &mut V) -> V::Result { + (**self).visit_with(visitor) + } +} + impl> TypeVisitable for Box { fn visit_with>(&self, visitor: &mut V) -> V::Result { (**self).visit_with(visitor) From b470b566d9ebe46862a432d24a82aefe3d364196 Mon Sep 17 00:00:00 2001 From: klensy Date: Sun, 16 Feb 2025 16:37:53 +0300 Subject: [PATCH 2/2] [dont merge] temporary allow git dep --- src/tools/tidy/src/deps.rs | 1 + src/tools/tidy/src/extdeps.rs | 2 ++ 2 files changed, 3 insertions(+) diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index d75a68d597348..08d233eb0aa8f 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -406,6 +406,7 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[ "tracing-log", "tracing-subscriber", "tracing-tree", + "triomphe", "twox-hash", "type-map", "typenum", diff --git a/src/tools/tidy/src/extdeps.rs b/src/tools/tidy/src/extdeps.rs index 55f937aeacf50..c6be5c82ecec1 100644 --- a/src/tools/tidy/src/extdeps.rs +++ b/src/tools/tidy/src/extdeps.rs @@ -8,6 +8,8 @@ const ALLOWED_SOURCES: &[&str] = &[ r#""registry+https://github.com/rust-lang/crates.io-index""#, // This is `rust_team_data` used by `site` in src/tools/rustc-perf, r#""git+https://github.com/rust-lang/team#a5260e76d3aa894c64c56e6ddc8545b9a98043ec""#, + // temporary to test + r#""git+https://github.com/Manishearth/triomphe.git?rev=6ff0527036632be33a6ed45e5e8a0fb6243dee47#6ff0527036632be33a6ed45e5e8a0fb6243dee47""#, ]; /// Checks for external package sources. `root` is the path to the directory that contains the