Skip to content

Commit b494846

Browse files
authored
Fix foreign-crate symbol registration (#4)
1 parent 943db7d commit b494846

File tree

10 files changed

+98
-5
lines changed

10 files changed

+98
-5
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@
22

33
## Next release
44

5+
### Bugfixes
6+
7+
- Fixed the `stringleton::enable!()` macro when referring to foreign crates.
8+
- Fixed usage of `sym!()` in external tests.
9+
510
### Dependencies
611

712
- Bumped `spin` to `0.10.0`.

Cargo.lock

Lines changed: 15 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@ members = [
77
"tests/dylib/dynamic-library",
88
"tests/dylib/c-dynamic-library",
99
"tests/check-codegen",
10+
"tests/foreign-crate-registry",
11+
"tests/foreign-crate",
1012
]
11-
default-members = ["stringleton", "stringleton-registry"]
13+
default-members = ["stringleton", "stringleton-registry", "tests/check-codegen", "tests/foreign-crate-registry", "tests/foreign-crate"]
1214
resolver = "3"
1315

1416
[workspace.dependencies]

stringleton/README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,11 @@ assert_eq!(message, message2);
6666
assert_eq!(message.as_str().as_ptr(), message2.as_str().as_ptr());
6767
```
6868

69+
**NOTE:** In external tests (i.e. those in a separate `tests/` subdirectory), each
70+
test file should call `stringleton::enable!(main_library_crate)` instead of
71+
`stringleton::enable!()`. See the documentation of the `enable!()` macro for more
72+
details.
73+
6974
## Crate features
7075

7176
- **std** *(enabled by default)*: Use synchronization primitives from the

stringleton/lib.rs

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,17 @@ macro_rules! static_sym {
149149
/// Put a call to this macro somewhere in the root of each crate that uses the
150150
/// `sym!(...)` macro.
151151
///
152+
/// The second variant reuses the symbol table of another crate, and this is
153+
/// particularly needed due to the way external tests (in the `tests/`
154+
/// subdirectory of the project) are compiled. Test files `tests/foo.rs`, are
155+
/// compiled as "pseudo-crates", so they are semantically a separate crate from
156+
/// the main library crate. But they are compiled into the same binary, so just
157+
/// using `stringleton::enable!()` without arguments will cause linker errors
158+
/// (`duplicate #[distributed_slice] with name "TABLE"`).
159+
///
160+
/// In external tests using [`sym!()`], the test file should instead use
161+
/// `stringleton::enable!(main_library_crate)`.
162+
///
152163
/// ## Details
153164
///
154165
/// This creates a "distributed slice" containing all symbols in this crate, as
@@ -184,11 +195,11 @@ macro_rules! enable {
184195
() => {
185196
#[doc(hidden)]
186197
#[cfg(not(any(miri, target_arch = "wasm32")))]
187-
pub(crate) mod _stringleton_enabled {
198+
pub mod _stringleton_enabled {
188199
#[$crate::internal::linkme::distributed_slice]
189200
#[linkme(crate = $crate::internal::linkme)]
190201
#[doc(hidden)]
191-
pub(crate) static TABLE: [$crate::internal::Site] = [..];
202+
pub static TABLE: [$crate::internal::Site] = [..];
192203

193204
$crate::internal::ctor::declarative::ctor! {
194205
#[ctor]
@@ -207,10 +218,10 @@ macro_rules! enable {
207218
#[cfg(not(any(miri, target_arch = "wasm32")))]
208219
pub use _stringleton_enabled::_stringleton_register_symbols;
209220
};
210-
($krate:path) => {
221+
($($krate:tt)+) => {
211222
#[doc(hidden)]
212223
#[cfg(not(any(miri, target_arch = "wasm32")))]
213-
pub(crate) use $krate::_stringleton_enabled;
224+
pub use $($krate)*::_stringleton_enabled;
214225
};
215226
}
216227

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
[package]
2+
name = "foreign-crate-registry"
3+
publish = false
4+
edition = "2024"
5+
6+
[lib]
7+
path = "lib.rs"
8+
test = true
9+
doctest = false
10+
11+
[lints]
12+
workspace = true
13+
14+
[dependencies]
15+
stringleton = { path = "../../stringleton", features = ["debug-assertions"] }
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
use stringleton::sym;
2+
3+
stringleton::enable!();
4+
5+
pub fn foo() -> stringleton::Symbol {
6+
sym!(foo)
7+
}

tests/foreign-crate/Cargo.toml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
[package]
2+
name = "foreign-crate"
3+
publish = false
4+
edition = "2024"
5+
6+
[lib]
7+
path = "lib.rs"
8+
test = true
9+
doctest = false
10+
11+
[lints]
12+
workspace = true
13+
14+
[dependencies]
15+
stringleton = { path = "../../stringleton", features = ["debug-assertions"] }
16+
foreign-crate-registry.path = "../foreign-crate-registry"

tests/foreign-crate/lib.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
stringleton::enable!(::foreign_crate_registry);
2+
3+
pub fn bar() -> stringleton::Symbol {
4+
stringleton::sym!(bar)
5+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
use foreign_crate::bar;
2+
use foreign_crate_registry::foo;
3+
use stringleton::sym;
4+
5+
// Forwarding to `foreign_crate_registry` through `foreign_crate`.
6+
stringleton::enable!(foreign_crate);
7+
8+
#[test]
9+
fn external_symbols_test() {
10+
assert_eq!(foo(), sym!(foo));
11+
assert_eq!(bar(), sym!(bar));
12+
}

0 commit comments

Comments
 (0)