Skip to content
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

Support multi-file ink! projects #259

Open
Robbepop opened this issue Nov 20, 2019 · 1 comment
Open

Support multi-file ink! projects #259

Robbepop opened this issue Nov 20, 2019 · 1 comment
Labels
A-ink_lang [ink_lang] Work item B-enhancement New feature or request

Comments

@Robbepop
Copy link
Collaborator

Robbepop commented Nov 20, 2019

Problem Description & Current State

Currently all ink! items are always defined in a single file.
The reason for this is that we only allow defining ink! definitions that have the known ink! markers such as #[ink(storage)], #[ink(event)] etc. to be defined within the ink!'s smart contract module:

#[ink::contract(version = "0.1.0")]
mod my_ink_contract_module {
    ...
}

This is becoming an increasing problem especially for more complex smart contracts as smart contract writers want to be able to specify certain parts of their smart contracts be be structurally in different files.

Potential Solution

A potential solution to solve this problem is to make use of so-called out-of-line modules that have a special marker to make it possible to annotate in which file those modules exist.

Rust already supports annotating out-of-line modules with the #[path = <module_path.rs>] marker. However, due to design rationals stated in this comment we might want to consider using a slightly different specialized ink! marker for the same purpose, e.g. #[ink(path = <module_path.rs>)].

The semantics of having such an annotated module within an ink! module would be the same as simply including the annotated module's code directly into the ink! module as if it was an inline module definition.

An example contract using this feature would then look like the following:

#[ink::contract(version = "0.1.0")]
mod my_contract {
    #[ink(storage)]
    pub struct MyStorage { ... }

    impl MyStorage {
        #[ink(constructor)]
        fn new(&mut self) { ... }

        #[ink(message)]
        fn do_something(&self) { ... }
    }

    #[ink(path = "my_contract_impls.rs")]
    mod my_contract_impls;
}

With my_contract_impls being a file such as:

use super::MyStorage;

impl MyStorage {
    #[ink(message)]
    fn do_something_else(&mut self) { ... }
}

Which would end up after initial expansion as:

#[ink::contract(version = "0.1.0")]
mod my_contract {
    #[ink(storage)]
    pub struct MyStorage { ... }

    impl MyStorage {
        #[ink(constructor)]
        fn new(&mut self) { ... }

        #[ink(message)]
        fn do_something(&self) { ... }
    }

    mod my_contract_impls {
        use super::MyStorage;

        impl MyStorage {
            #[ink(message)]
            fn do_something_else(&mut self) { ... }
        }
    }
}

Hard Problems To Solve First

To make this work properly we'd need to recursively check all the definitions inside those expanded inline-modules for special ink! definitions and properly make use of them or report errors.

A big problem might become reporting error with correct span information of those out-of-line modules since we want to report the errors with their original span information of the out-of-line module, not of the post-expanded inline-module definition.

@Robbepop Robbepop added A-ink_lang [ink_lang] Work item B-enhancement New feature or request D-hard and removed D-hard labels Nov 20, 2019
@wottpal
Copy link
Contributor

wottpal commented Sep 6, 2022

Hey there! Recently discovered ink! and I love it! This problem however seems like a dealbreaker for collaborative work on bigger-scale projects. Is there any ETA if and when this gets resolved?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-ink_lang [ink_lang] Work item B-enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants