Skip to content

Resolver: Arc<dyn Fn> with a non-breaking impl Fn constructor - #15

Closed
mwaddip wants to merge 3 commits into
ergoplatform:mainfrom
mwaddip:feat/resolver-arc-dyn-fn
Closed

Resolver: Arc<dyn Fn> with a non-breaking impl Fn constructor#15
mwaddip wants to merge 3 commits into
ergoplatform:mainfrom
mwaddip:feat/resolver-arc-dyn-fn

Conversation

@mwaddip

@mwaddip mwaddip commented Jun 8, 2026

Copy link
Copy Markdown

Replaces #10. That PR was opened from mwaddip:main and, as the fork's main advanced, accreted commits belonging to #11/#13/#14; this is a self-contained 2-commit branch off main.

Changes the Resolver type from a bare fn pointer to Arc<dyn Fn(&Digest32) -> Node + Send + Sync>, so persistence/storage backends can hold captured state.

To keep it non-breaking, AVLTree::new now accepts impl Fn(&Digest32) -> Node + Send + Sync + 'static and wraps it in the Arc internally — callers written against the old fn-pointer signature (e.g. ergotree-interpreter's 13 bare-closure sites) compile unchanged. Callers holding a prebuilt Resolver construct the struct literally (resolver is pub).

All crate tests pass.

mwaddip and others added 2 commits April 4, 2026 16:35
…upport

The Resolver type was defined as a bare function pointer (fn(&Digest32) -> Node),
which cannot capture state. This makes it impossible to implement VersionedAVLStorage
with a real storage backend — the resolver needs to load nodes from a database, but
a function pointer cannot hold a database reference.

Changed to Arc<dyn Fn(&Digest32) -> Node + Send + Sync> which allows closures that
capture storage handles. Arc (not Box) because AVLTree derives Clone. Send + Sync
for thread safety with concurrent readers.

All 22 existing tests pass unchanged (modulo wrapping bare functions in Arc::new).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
28862a1 changed Resolver from a plain fn pointer to Arc<dyn Fn> for the
persistence backend, which broke every caller written against the old
signature (sigma-rust's interpreter passes bare closures at 13 sites).
Take `impl Fn(&Digest32) -> Node + Send + Sync + 'static` and wrap it in
the Arc inside the constructor: fn-pointer-era callers compile unchanged,
capturing closures (the persistence resolver) pass straight in without
their own Arc::new. Callers holding a prebuilt Resolver construct the
struct literally — `resolver` is a pub field.

Internal call sites (prover test + tests/common) updated to drop the
now-redundant Arc::new.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
… Arc resolvers

a4a2aa7 changed new() to take impl Fn, which fixed bare-closure callers
(ergotree-interpreter's 13 sites) but BREAKS callers holding a pre-built
Resolver (Arc<dyn Fn>): Arc<dyn Fn> does not implement Fn, so the node's
persistence-backend resolvers are rejected with E0277.

Introduce IntoResolver, implemented for both F: Fn(...) (Arc-wrapped here)
and Resolver (passed through, no re-wrap), and take impl IntoResolver in
new(). The two impls don't overlap precisely because Arc<dyn Fn> isn't Fn.
Serves the interpreter and the node from one constructor; the internal
bare-closure call sites are unaffected.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@mwaddip

mwaddip commented Jun 8, 2026

Copy link
Copy Markdown
Author

Superseded by #16. #15 carried the impl IntoResolver constructor shape, which breaks callers passing bare unannotated closures (E0282) — including the interpreter's 13 AVLTree::new(|digest| …) sites. #16 keeps new(impl Fn) (non-breaking for those) and adds a separate with_resolver(Resolver) for pre-built Arc resolvers (the node).

@mwaddip mwaddip closed this Jun 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant