From 05e2ef029e0d751e8bc058c240c6e5ddc090c930 Mon Sep 17 00:00:00 2001 From: Jake Hughes Date: Mon, 4 Nov 2024 17:36:50 +0000 Subject: [PATCH] Use custom hashbrown implementation This supports finalizer elision by implementing DropMethodFinalizerElidable on the backing table. --- Cargo.lock | 16 ++++++++--- library/std/Cargo.toml | 2 +- src/tools/tidy/src/extdeps.rs | 3 +- tests/ui/static/gc/elision/hashmap.rs | 27 ++++++++++++++++++ tests/ui/static/gc/elision/hashset.rs | 41 +++++++++++++++++++++++++++ 5 files changed, 83 insertions(+), 6 deletions(-) create mode 100644 tests/ui/static/gc/elision/hashmap.rs create mode 100644 tests/ui/static/gc/elision/hashset.rs diff --git a/Cargo.lock b/Cargo.lock index a692298392528..2eb960e110a97 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1666,6 +1666,14 @@ checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" dependencies = [ "ahash", "allocator-api2", +] + +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "git+https://github.com/softdevteam/alloy_hashbrown?branch=elide_finalisers#c40d6530b95732913ee6c65185784f2ebe56d242" +dependencies = [ + "allocator-api2", "compiler_builtins", "rustc-std-workspace-alloc", "rustc-std-workspace-core", @@ -1995,7 +2003,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" dependencies = [ "equivalent", - "hashbrown", + "hashbrown 0.14.3", "rustc-rayon", "serde", ] @@ -2657,7 +2665,7 @@ dependencies = [ "compiler_builtins", "crc32fast", "flate2", - "hashbrown", + "hashbrown 0.14.3", "indexmap", "memchr", "rustc-std-workspace-alloc", @@ -5278,7 +5286,7 @@ dependencies = [ "core", "dlmalloc", "fortanix-sgx-abi", - "hashbrown", + "hashbrown 0.14.5", "hermit-abi", "libc", "miniz_oxide", @@ -5585,7 +5593,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4db52ee8fec06e119b692ef3dd2c4cf621a99204c1b8c47407870ed050305b9b" dependencies = [ "gimli", - "hashbrown", + "hashbrown 0.14.3", "object 0.32.2", "tracing", ] diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml index e1e21289a7e9d..62b0a155e3a7c 100644 --- a/library/std/Cargo.toml +++ b/library/std/Cargo.toml @@ -21,7 +21,7 @@ core = { path = "../core", public = true } compiler_builtins = { version = "0.1.105" } profiler_builtins = { path = "../profiler_builtins", optional = true } unwind = { path = "../unwind" } -hashbrown = { version = "0.14", default-features = false, features = ['rustc-dep-of-std'] } +hashbrown = { git = "https://github.com/softdevteam/alloy_hashbrown", branch = "elide_finalisers", default-features = false, features = ['rustc-dep-of-std'] } std_detect = { path = "../stdarch/crates/std_detect", default-features = false, features = ['rustc-dep-of-std'] } # Dependencies of the `backtrace` crate diff --git a/src/tools/tidy/src/extdeps.rs b/src/tools/tidy/src/extdeps.rs index ff71ca537256f..137924177d82b 100644 --- a/src/tools/tidy/src/extdeps.rs +++ b/src/tools/tidy/src/extdeps.rs @@ -5,6 +5,7 @@ use std::path::Path; /// List of allowed sources for packages. const ALLOWED_SOURCES: &[&str] = &["\"registry+https://github.com/rust-lang/crates.io-index\""]; +const ALLOY_HASHBROWN: &str = "alloy_hashbrown"; /// Checks for external package sources. `root` is the path to the directory that contains the /// workspace `Cargo.toml`. @@ -33,7 +34,7 @@ pub fn check(root: &Path, bad: &mut bool) { let source = line.split_once('=').unwrap().1.trim(); // Ensure source is allowed. - if !ALLOWED_SOURCES.contains(&&*source) { + if !ALLOWED_SOURCES.contains(&&*source) && !source.contains(ALLOY_HASHBROWN) { tidy_error!(bad, "invalid source: {}", source); } } diff --git a/tests/ui/static/gc/elision/hashmap.rs b/tests/ui/static/gc/elision/hashmap.rs new file mode 100644 index 0000000000000..ac3757570ce8d --- /dev/null +++ b/tests/ui/static/gc/elision/hashmap.rs @@ -0,0 +1,27 @@ +//@ run-pass +// ignore-tidy-linelength +#![feature(gc)] +#![allow(dead_code)] +include!{"./auxiliary/types.rs"} + +use std::mem::needs_finalizer; +use std::collections::HashMap; +use std::gc::Gc; + +static HM_TRIVIAL: bool = needs_finalizer::>(); +static HM_FIN_KEY: bool = needs_finalizer::>(); +static HM_FIN_VAL: bool = needs_finalizer::>(); +static HM_FIN_BOTH: bool = needs_finalizer::>(); +static HM_FIN_GC_KEY: bool = needs_finalizer::, Gc>>(); +static HM_FIN_GC_VAL: bool = needs_finalizer::, Gc>>(); +static HM_FIN_GC_BOTH: bool = needs_finalizer::, Gc>>(); + +fn main() { + assert!(!HM_TRIVIAL); + assert!(HM_FIN_KEY); + assert!(HM_FIN_VAL); + assert!(HM_FIN_BOTH); + assert!(!HM_FIN_GC_KEY); + assert!(!HM_FIN_GC_VAL); + assert!(!HM_FIN_GC_BOTH); +} diff --git a/tests/ui/static/gc/elision/hashset.rs b/tests/ui/static/gc/elision/hashset.rs new file mode 100644 index 0000000000000..0b74572b30f81 --- /dev/null +++ b/tests/ui/static/gc/elision/hashset.rs @@ -0,0 +1,41 @@ +//@ run-pass +// ignore-tidy-linelength +#![feature(gc)] +#![allow(dead_code)] +include!{"./auxiliary/types.rs"} + +use std::mem::needs_finalizer; +use std::collections::HashSet; +use std::gc::Gc; + +static HS_TRIVIAL: bool = needs_finalizer::>(); +static HS_FINALIZABLE: bool = needs_finalizer::>(); +static HS_UNFINALIZABLE: bool = needs_finalizer::>(); +static HS_TUPLE_UNFINALIZABLE: bool = needs_finalizer::>(); +static HS_TUPLE_FINALIZABLE: bool = needs_finalizer::>(); +static HS_TUPLE_CONTAINS_FINALIZABLE: bool = needs_finalizer::>(); +static HS_HS_FINALIZABLE: bool = needs_finalizer::>>(); +static HS_HS_UNFINALIZABLE: bool = needs_finalizer::>>(); +static HS_STRING: bool = needs_finalizer::>(); +static HS_BOX_FINALIZABLE: bool = needs_finalizer::>>(); +static HS_BOX_UNFINALIZABLE: bool = needs_finalizer::>>(); +static HS_TUPLE_GC_UNFINALIZABLE: bool = needs_finalizer::)>>(); +static HS_TUPLE_GC_FINALIZABLE: bool = needs_finalizer::)>>(); +static HS_COLLECTABLE_NO_DROP_ELEMENT: bool = needs_finalizer::>(); + +fn main() { + assert!(!HS_TRIVIAL); + assert!(HS_FINALIZABLE); + assert!(!HS_UNFINALIZABLE); + assert!(!HS_TUPLE_UNFINALIZABLE); + assert!(HS_TUPLE_FINALIZABLE); + assert!(HS_TUPLE_CONTAINS_FINALIZABLE); + assert!(HS_HS_FINALIZABLE); + assert!(!HS_HS_UNFINALIZABLE); + assert!(!HS_STRING); + assert!(HS_BOX_FINALIZABLE); + assert!(!HS_BOX_UNFINALIZABLE); + assert!(!HS_TUPLE_GC_UNFINALIZABLE); + assert!(HS_TUPLE_GC_FINALIZABLE); + assert!(!HS_COLLECTABLE_NO_DROP_ELEMENT); +}