-
Notifications
You must be signed in to change notification settings - Fork 69
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow contractimpls across mods #1322
Conversation
…t no predictable path to the mod is needed
TODO:
|
I think we should merge this as is, even if there are some edge cases not covered, because it covers an 80% of what's required to get it to work, and the edge cases may require significantly more refactoring. So it'd be good to get the minimal merged so that the refactor can be broken up, and be easier to review. We can create follow up issues after this change merges. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's really nice, thanks!
What
Add a new trait
ContractFunctionRegister
that wraps the existingregister
function that all contracts use to create a table of all their functions.Why
When a contract is registered with the test environment it uses the table of functions to know what functions a contract has defined.
Today contract functions get added to the table by using the ctor crate to call the
#mod::register
function where#mod
is a generated module at the same location as where the#[contract]
macro gets used.The problem with this, and that was reported in #1321, is that it's valid in Rust to place type implementations anywhere in a crate that is able to reference the type, but there's no way for the generated code to know what relative or absolute path to use to reference that
#mod
.The generated code assumes that the
#mod
is imported into the current scope, which it never will be because users have no reason to manually do it because it is hidden from them and they don't know it exists.This situation leads to the following error that makes little sense to a developer because it refers to hidden generated code:
Most of the time when folks add additional
impl
blocks to a type they will import the type into the current module so as to reference it, and so we can improve the existing situation by shifting the call to#mod::register
to be a call toContract::register
.To ensure that the
register
function does not clash with a contract function that may also be namedregister
the function is defined on a hidden trait,ContractFunctionRegister
, and is only used in the context of that trait.There are some other minor changes included that remove assumptions about the type name of a contract being a simple identifier, so that when it is more than an identifier, such as a path (e.g.
path::Identifier
), the full type name is preserved everywhere it is needed.Close #1321