From 73cd5a2c94cee7956a0e66712eb88849e2da704d Mon Sep 17 00:00:00 2001 From: Simon Ask Ulsnes Date: Tue, 16 Dec 2025 14:39:07 +0100 Subject: [PATCH 1/2] Fix foreign-crate symbol registration --- CHANGELOG.md | 5 +++++ Cargo.lock | 15 +++++++++++++++ Cargo.toml | 4 +++- stringleton/README.md | 5 +++++ stringleton/lib.rs | 19 +++++++++++++++---- tests/foreign-crate-registry/Cargo.toml | 15 +++++++++++++++ tests/foreign-crate-registry/lib.rs | 7 +++++++ tests/foreign-crate/Cargo.toml | 16 ++++++++++++++++ tests/foreign-crate/lib.rs | 5 +++++ tests/foreign-crate/tests/external_test.rs | 12 ++++++++++++ 10 files changed, 98 insertions(+), 5 deletions(-) create mode 100644 tests/foreign-crate-registry/Cargo.toml create mode 100644 tests/foreign-crate-registry/lib.rs create mode 100644 tests/foreign-crate/Cargo.toml create mode 100644 tests/foreign-crate/lib.rs create mode 100644 tests/foreign-crate/tests/external_test.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index 00fda63..220f5b6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,11 @@ ## Next release +### Bugfixes + +- Fixed the `stringleton::enable!()` macro when referring to foreign crates. +- Fixed usage of `sym!()` in external tests. + ### Dependencies - Bumped `spin` to `0.10.0`. diff --git a/Cargo.lock b/Cargo.lock index 486e3ce..d344d8d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -113,6 +113,21 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" +[[package]] +name = "foreign-crate" +version = "0.0.0" +dependencies = [ + "foreign-crate-registry", + "stringleton", +] + +[[package]] +name = "foreign-crate-registry" +version = "0.0.0" +dependencies = [ + "stringleton", +] + [[package]] name = "hashbrown" version = "0.16.1" diff --git a/Cargo.toml b/Cargo.toml index 5ab3b4f..5e96b93 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,8 +7,10 @@ members = [ "tests/dylib/dynamic-library", "tests/dylib/c-dynamic-library", "tests/check-codegen", + "tests/foreign-crate-registry", + "tests/foreign-crate", ] -default-members = ["stringleton", "stringleton-registry"] +default-members = ["stringleton", "stringleton-registry", "tests/check-codegen", "tests/foreign-crate-registry", "tests/foreign-crate"] resolver = "3" [workspace.dependencies] diff --git a/stringleton/README.md b/stringleton/README.md index c2239c1..2f54db3 100644 --- a/stringleton/README.md +++ b/stringleton/README.md @@ -66,6 +66,11 @@ assert_eq!(message, message2); assert_eq!(message.as_str().as_ptr(), message2.as_str().as_ptr()); ``` +**NOTE:** In external tests (i.e. those in a separate `tests/` subdirectory), each +test file should call `stringleton::enable!(main_library_crate)` instead of +`stringleton::enable!()`. See the documentation of the `enable!()` macro for more +details. + ## Crate features - **std** *(enabled by default)*: Use synchronization primitives from the diff --git a/stringleton/lib.rs b/stringleton/lib.rs index c9465fb..5603b43 100644 --- a/stringleton/lib.rs +++ b/stringleton/lib.rs @@ -149,6 +149,17 @@ macro_rules! static_sym { /// Put a call to this macro somewhere in the root of each crate that uses the /// `sym!(...)` macro. /// +/// The second variant reuses the symbol table of another crate, and this is +/// particularly needed due to the way external tests (in the `tests/` +/// subdirectory of the project) are compiled. Test files `tests/foo.rs`, are +/// compiled as "pseudo-crates", so they are semantically a separate crate from +/// the main library crate. But they are compiled into the same binary, so just +/// using `stringleton::enable!()` without arguments will cause linker errors +/// (`duplicate #[distributed_slice] with name "TABLE"`). +/// +/// In external tests using [`sym!()`], the test file should instead use +/// `stringleton::enable!(main_library_crate)`. +/// /// ## Details /// /// This creates a "distributed slice" containing all symbols in this crate, as @@ -184,11 +195,11 @@ macro_rules! enable { () => { #[doc(hidden)] #[cfg(not(any(miri, target_arch = "wasm32")))] - pub(crate) mod _stringleton_enabled { + pub mod _stringleton_enabled { #[$crate::internal::linkme::distributed_slice] #[linkme(crate = $crate::internal::linkme)] #[doc(hidden)] - pub(crate) static TABLE: [$crate::internal::Site] = [..]; + pub static TABLE: [$crate::internal::Site] = [..]; $crate::internal::ctor::declarative::ctor! { #[ctor] @@ -207,10 +218,10 @@ macro_rules! enable { #[cfg(not(any(miri, target_arch = "wasm32")))] pub use _stringleton_enabled::_stringleton_register_symbols; }; - ($krate:path) => { + ($($krate:tt)+) => { #[doc(hidden)] #[cfg(not(any(miri, target_arch = "wasm32")))] - pub(crate) use $krate::_stringleton_enabled; + pub use $($krate)*::_stringleton_enabled; }; } diff --git a/tests/foreign-crate-registry/Cargo.toml b/tests/foreign-crate-registry/Cargo.toml new file mode 100644 index 0000000..3547714 --- /dev/null +++ b/tests/foreign-crate-registry/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "foreign-crate-registry" +publish = false +edition = "2024" + +[lib] +path = "lib.rs" +test = true +doctest = false + +[lints] +workspace = true + +[dependencies] +stringleton = { path = "../../stringleton", features = ["debug-assertions"] } diff --git a/tests/foreign-crate-registry/lib.rs b/tests/foreign-crate-registry/lib.rs new file mode 100644 index 0000000..da600aa --- /dev/null +++ b/tests/foreign-crate-registry/lib.rs @@ -0,0 +1,7 @@ +use stringleton::sym; + +stringleton::enable!(); + +pub fn foo() -> stringleton::Symbol { + sym!(foo) +} diff --git a/tests/foreign-crate/Cargo.toml b/tests/foreign-crate/Cargo.toml new file mode 100644 index 0000000..ad242fd --- /dev/null +++ b/tests/foreign-crate/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "foreign-crate" +publish = false +edition = "2024" + +[lib] +path = "lib.rs" +test = true +doctest = false + +[lints] +workspace = true + +[dependencies] +stringleton = { path = "../../stringleton", features = ["debug-assertions"] } +foreign-crate-registry.path = "../foreign-crate-registry" diff --git a/tests/foreign-crate/lib.rs b/tests/foreign-crate/lib.rs new file mode 100644 index 0000000..2a5d8cc --- /dev/null +++ b/tests/foreign-crate/lib.rs @@ -0,0 +1,5 @@ +stringleton::enable!(::foreign_crate_registry); + +pub fn bar() -> stringleton::Symbol { + stringleton::sym!(bar) +} diff --git a/tests/foreign-crate/tests/external_test.rs b/tests/foreign-crate/tests/external_test.rs new file mode 100644 index 0000000..e10a9a7 --- /dev/null +++ b/tests/foreign-crate/tests/external_test.rs @@ -0,0 +1,12 @@ +use foreign_crate::bar; +use foreign_crate_registry::foo; +use stringleton::sym; + +// Forwarding to `foreign_crate_registry` through `foreign_crate`. +stringleton::enable!(foreign_crate); + +#[test] +fn external_symbols_test() { + assert_eq!(foo(), sym!(foo)); + assert_eq!(bar(), sym!(bar)); +} From 137faf7ade180e2c1a4d5f80218f7ac776008524 Mon Sep 17 00:00:00 2001 From: Simon Ask Ulsnes Date: Tue, 16 Dec 2025 14:43:02 +0100 Subject: [PATCH 2/2] Release 0.2.1 --- CHANGELOG.md | 2 +- Cargo.lock | 6 +++--- stringleton-dylib/Cargo.toml | 4 ++-- stringleton-registry/Cargo.toml | 2 +- stringleton/Cargo.toml | 4 ++-- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 220f5b6..a37957c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -## Next release +## 0.2.1 - 2025-12-16 ### Bugfixes diff --git a/Cargo.lock b/Cargo.lock index d344d8d..48b3c3e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -334,7 +334,7 @@ checksum = "d5fe4ccb98d9c292d56fec89a5e07da7fc4cf0dc11e156b41793132775d3e591" [[package]] name = "stringleton" -version = "0.2.0" +version = "0.2.1" dependencies = [ "ctor", "hashbrown", @@ -345,7 +345,7 @@ dependencies = [ [[package]] name = "stringleton-dylib" -version = "0.2.0" +version = "0.2.1" dependencies = [ "ctor", "linkme", @@ -354,7 +354,7 @@ dependencies = [ [[package]] name = "stringleton-registry" -version = "0.2.0" +version = "0.2.1" dependencies = [ "hashbrown", "once_cell", diff --git a/stringleton-dylib/Cargo.toml b/stringleton-dylib/Cargo.toml index 9cfa85a..89f76ea 100644 --- a/stringleton-dylib/Cargo.toml +++ b/stringleton-dylib/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "stringleton-dylib" -version = "0.2.0" +version = "0.2.1" edition = "2024" authors = ["Simon Ask Ulsnes "] license = "MIT OR Apache-2.0" @@ -16,7 +16,7 @@ crate-type = ["dylib"] [dependencies] ctor.workspace = true linkme.workspace = true -stringleton-registry = { version = "0.2.0", path = "../stringleton-registry", default-features = false } +stringleton-registry = { version = "0.2.1", path = "../stringleton-registry", default-features = false } [features] default = ["std"] diff --git a/stringleton-registry/Cargo.toml b/stringleton-registry/Cargo.toml index 5855663..ae9d152 100644 --- a/stringleton-registry/Cargo.toml +++ b/stringleton-registry/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "stringleton-registry" -version = "0.2.0" +version = "0.2.1" edition = "2024" authors = ["Simon Ask Ulsnes "] license = "MIT OR Apache-2.0" diff --git a/stringleton/Cargo.toml b/stringleton/Cargo.toml index dc08e84..d03e784 100644 --- a/stringleton/Cargo.toml +++ b/stringleton/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "stringleton" -version = "0.2.0" +version = "0.2.1" edition = "2024" authors = ["Simon Ask Ulsnes "] license = "MIT OR Apache-2.0" @@ -16,7 +16,7 @@ crate-type = ["rlib"] [dependencies] ctor.workspace = true linkme.workspace = true -stringleton-registry = { version = "0.2.0", path = "../stringleton-registry", default-features = false } +stringleton-registry = { version = "0.2.1", path = "../stringleton-registry", default-features = false } [dev-dependencies] hashbrown.workspace = true