Skip to content

ink! Plugin #163

Closed
Closed
@Robbepop

Description

@Robbepop

ink! 2.0

This is the tracking issue for implementing ink! as a Rust compiler plugin.

Motivation

In #153 we already uncovered problems with the current approach to how the big-fat-macro approach in ink! has serious downsides in usability and functionality.

Structure

Here we are collecting design and work items to be done via single, independent PRs.

Example

Flipper smart contract syntax idea with the ink! plugin.

#![plugin(ink_plugin)]

use ink_core::storage;

/// This is the storage state struct of our Flipper contract.
///
/// It only requires the `#[ink::contract]` annotation in order for ink! to know that it is going
/// to be the contract's state.
///
/// Implementation blocks associated to Flipper are treated specially and `pub fn`s are going
/// to be messages of the Flipper smart contract whereas private `fn`s are simple methods.
#[ink::contract]
struct Flipper {
    value: storage::Value<bool>,
}

impl Flipper {
    /// This is the constructor.
    ///
    /// It should be possible for a rustc plugin to factor out which methods are constructors
    /// and thus provide them as deploy handlers. This requires another refactoring of `ink_model`
    /// in order to allow for multiple deploy handlers.
    pub fn new() -> Self {
        Flipper::from_bool(true)
    }

    /// Instantiates the Flipper with the given boolean value.
    pub fn from_bool(value: bool) -> Self {
        Flipper { value }
    }

    /// Flips the value of the internal bool.
    ///
    /// No longer need `pub(external)` since we want to come as closely to natural Rust syntax as possible.
    pub fn flip(&mut self) {
         *self.value = !*self.value;
    }

    /// Returns the internal bool.
    pub fn get(&self) {
        *self.value
    }
}

Docs

Since documentation about Rust compiler plugins are rare and oftentimes outdated we are trying to collect some materials on how to get up and running with information about how to write Rust compiler plugins.

Section Description Link
Tutorial: Syntax Extensions Another tutorial extending on top of the unstable book. https://www.gulshansingh.com/posts/how-to-write-a-rust-syntax-extension/
[feature(plugin)] Technical description of the unstable plugin crate feature. https://doc.rust-lang.org/nightly/unstable-book/language-features/plugin.html
Blogpost: Plugins A blog post about how to create plugins for rustc. http://adventures.michaelfbryan.com/posts/plugins-in-rust/
Rustc: Developer Docs Developer documentation of the Rust compiler internal libraries. https://doc.rust-lang.org/nightly/nightly-rustc/syntax/index.html
Rustc Guide The official guide to hack on the Rust compiler. The linked section provides information about how the Rust compiler works internally. https://rust-lang.github.io/rustc-guide/part-2-intro.html
Oasis Labs Doing something similar to what ink! is planning to do in the future. https://github.com/oasislabs/oasis-rs/tree/master/oasis-build
Clippy Driver Doing exactly what ink! plugin shall be doing using #[feature(rustc_private)] https://github.com/rust-lang/rust-clippy/blob/master/src/driver.rs

Intermediate Knowledge Sharing

Another go at the problem of macros not being able to see the whole context of their invocation might be solvable by introducing knowledge sharing across macro boundaries. For this we would no longer operate on a single contract! macro but instead operate on many different macros and custom attributes. All of them have to support some way of sharing their local view on the code to assembly a greater scheme of the code.
This could be done by writing back collected knowledge about the contract code into files at the target directory of a smart contract.
These files could be written to and queried about information of other macro instantiations.

The major downside of this approach is that macro evaluation is generally unordered and cannot be relied upon. This further means that no macro strictly knows if information collected by other macros is already covered and if all necessary information has already been collected. It might be solvable by introducing special guards inside the files that store this information but making this process robust is a significant undertaking if possible at all.

Metadata

Metadata

Assignees

Labels

B-designDesigning a new component, interface or functionality.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions