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

ink! Plugin #163

Closed
Robbepop opened this issue Aug 7, 2019 · 2 comments
Closed

ink! Plugin #163

Robbepop opened this issue Aug 7, 2019 · 2 comments
Assignees
Labels
B-design Designing a new component, interface or functionality.

Comments

@Robbepop
Copy link
Collaborator

Robbepop commented Aug 7, 2019

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.

@Robbepop Robbepop added A-ink_plugin B-design Designing a new component, interface or functionality. labels Aug 14, 2019
@jplatte
Copy link

jplatte commented Oct 12, 2019

Plugins are now officially deprecated: rust-lang/rust#64675

@Robbepop Robbepop removed the D-hard label Nov 22, 2019
@Robbepop
Copy link
Collaborator Author

Robbepop commented Feb 3, 2020

Due to Rust plugins being officially deprecated we no longer follow this strategy. Closed.

@Robbepop Robbepop closed this as completed Feb 3, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
B-design Designing a new component, interface or functionality.
Projects
None yet
Development

No branches or pull requests

3 participants