fix: use deterministic keys in element! macro for reproducible builds#187
Conversation
2745041 to
dba0150
Compare
|
Thanks for the PR! I think there are situations where this could cause conflicts. For example, a library which provides a component like so might encounter conflicts since the element! {
Foo {}
#(children)
}Maybe there's a way to guarantee uniqueness across compilation units by using |
Include module_path!() in generated element keys so that keys are unique across compilation units, not just within a single crate. This prevents key conflicts when library and user elements become siblings via #(children) interpolation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
dba0150 to
c2d4a82
Compare
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #187 +/- ##
=======================================
Coverage 87.71% 87.71%
=======================================
Files 35 35
Lines 5525 5526 +1
Branches 5525 5526 +1
=======================================
+ Hits 4846 4847 +1
Misses 570 570
Partials 109 109
🚀 New features to boost your workflow:
|
|
Thanks for the review! Good catch on the cross-crate collision issue. I've updated the implementation to include |
|
Lgtm! |
Summary
Uuid::new_v4()with a deterministic atomic counter for element declaration keys in theelement!macrouuiddependency fromiocraft-macrosProblem
The
element!macro usesUuid::new_v4()to generate unique keys for each element declaration. SinceUuid::new_v4()reads from/dev/urandom, it produces different output on every compilation. This makes any crate usingelement!non-reproducible: two compilations of the same source with the same flags produce different.rmetaand.ofiles.This breaks build systems that rely on reproducible builds, such as Nix with crate2nix/buildRustCrate. In that setup, crates are compiled independently and can be cached. When a cached crate has different metadata (SVH) than what a locally-built dependent expects, rustc produces
E0463 "can't find crate"link errors.Fix
Proc macro expansion order is deterministic within a compilation, so a simple atomic counter produces stable, unique keys. The counter resets to 0 at the start of each compilation (since proc macro state is not persisted), ensuring identical output for identical input.
Test plan
deterministic_keystest verifies same call site produces same key and different call sites produce different keys🤖 Generated with Claude Code