Implicitly specify whether contractimpl should be exported using CARGO_PRIMARY_PACKAGE #407
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
What
Base whether contractimpl functions are exported as callable wasm functions and in the contract spec on whether CARGO_PRIMARY_PACKAGE is set.
Why
The environment variable CARGO_PRIMARY_PACKAGE is set when a crate is being built as the primary crate, and it isn't set when a crate is being built as a dependency.
It is not particularly intuitive that if you import a crate that contains a contract that the contractimpls of that crate will be exported as callable functions of your crate. In fact, I would go as far to say that this is so surprising that it could result in contract developers accidentally exposing functions from other contracts that they wish to wrap or import for shared types.
We support this use case today with the
export_if
attribute oncontractimpl
that allows a contract developer to specify a build feature that should be used to gate the exporting on. i.e. If the feature is enabled, the functions are exported. If the feature is disabled, the functions are not exported. This solution of using a feature flag provides flexibility, but at a cost of verbosity, and still relies on developers importing the package to remember to do the right thing by configuring the features appropriately. The solution of feature flags also requires developers to opt-in, which means a developer who doesn't choose to useexport_if
will break other contracts who import it.It could be argued that using the
CARGO_PRIMARY_PACKAGE
is both magical and limiting since it is outside the developers control, but actually it is the same level of capability, it just flips what the default behavior is. With this change the default behavior is no contractimpl is reexported by the importing crate. A developer who wishes to reexport a dependencies contractimpl must do so explicitly by creating a contract type, writing animpl
block, and calling through to the dependencies contract type. This is mildly inconvenient, and if there is shown to be significant demand for this type of code we can add a macro that simplifies the whole process.Note that this change doesn't change whether
contracttype
s are exposed, since importing a crate that hascontracttype
s is likely to use thosecontracttype
s. There's an assumption here that we can revisit at a later point.