Skip to content

Commit

Permalink
Merge branch 'master' of github.com:paritytech/ink into robin-base-ke…
Browse files Browse the repository at this point in the history
…y-on-u8x32

# Conflicts:
#	.config/cargo_spellcheck.dic
  • Loading branch information
Robbepop committed Oct 20, 2021
2 parents 5a0481f + e8d4739 commit d87fc87
Show file tree
Hide file tree
Showing 406 changed files with 11,734 additions and 4,716 deletions.
8 changes: 6 additions & 2 deletions .config/cargo_spellcheck.dic
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ defrag
defragmentation
deploy
dereferencing
deserializes
dispatchable
deserialize/S
dispatchable/S
encodable
evaluable
fuzzer
Expand Down Expand Up @@ -96,5 +96,9 @@ runtime/S
struct/S
vec/S
vector/S
implementer/S
deduplicated
wildcard/S
natively
payability
unpayable
3 changes: 2 additions & 1 deletion .gitlab-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,8 @@ fmt:
script:
- cargo fmt --verbose --all -- --check
# For the UI tests we need to disable the license check
- cargo fmt --verbose --all -- --check --config=license_template_path="" crates/lang/macro/tests/ui/contract/{pass,fail}/*.rs
- cargo fmt --verbose --all -- --check --config=license_template_path="" crates/lang/tests/ui/contract/{pass,fail}/*.rs
- cargo fmt --verbose --all -- --check --config=license_template_path="" crates/lang/tests/ui/trait_def/{pass,fail}/*.rs


#### stage: examples
Expand Down
44 changes: 44 additions & 0 deletions RELEASES.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,47 @@
# Version 3.0-rc7 (UNRELEASED)

This is the 7th release candidate for ink! 3.0.

## Added

- The ink! codegen now heavily relies on static type information based on traits defined in `ink_lang`.
- Some of those traits and their carried information can be used for static reflection of ink!
smart contracts. Those types and traits reside in the new `ink_lang::reflect` module and is
publicly usable by ink! smart contract authors.

## Changed

- ink! Contract via `#[ink::contract]`:
- ink! smart contracts now always generated two contract types. Given `MyContract`:

- `MyContract` will still be the storage struct.
However, it can now additionally be used as static dependency in other smart contracts.
Static dependencies can be envisioned as being directly embedded into a smart contract.
- `MyContractRef` is pretty much the same of what we had gotten with the old `ink-as-dependency`.
It is a typed thin-wrapper around an `AccountId` that is mirroring the ink! smart contract's API
and implemented traits.
- ink! Trait Definitions via `#[ink::trait_definition]`:
- ink! trait definitions no longer can define trait constructors.
- ink! trait implementations now inherit `selector` and `payable` properties for trait messages.
- Now explicitly setting `selector` or `payable` property for an implemented ink! trait method
will only act as a guard that the set property is in fact the same as defined by the ink!
trait definition.
- Improve quite a few ink! specific compile errors:
- For example when using ink! messages and constructors that have inputs or outputs that cannot
be encoded or decoded using the SCALE codec.
- Simplified selector computation for ink! trait methods.
- Now selectors are encoded as `blake2b({namespace}::{trait_identifier}::{message_identifier})[0..4]`.
If no `namespace` is set for the ink! trait definition then the formula is
`blake2b({trait_identifier}::{message_identifier})[0..4]`.
Where `trait_identifier` and `message_identifier` both refer to the identifiers of the ink! trait
definition and ink! trait message respectively.

## Fixed

- Contracts that are compiled as root (the default) now properly revert the transaction if a message
returned `Result::Err`.
- This does not apply to ink! smart contracts that are used as dependencies. Therefore it is still possible to match against a result return type for a called dependency.

# Version 3.0-rc6

This is the 6th release candidate for ink! 3.0.
Expand Down
15 changes: 13 additions & 2 deletions crates/lang/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,13 @@ ink_lang_macro = { version = "3.0.0-rc6", path = "macro", default-features = fal

scale = { package = "parity-scale-codec", version = "2", default-features = false, features = ["derive", "full"] }
derive_more = { version = "0.99", default-features = false, features = ["from"] }
static_assertions = "1.1"

[dev-dependencies]
# required for the doctest of `env_access::EnvAccess::instantiate_contract`
ink_lang_ir = { version = "3.0.0-rc6", path = "ir" }
ink_metadata = { version = "3.0.0-rc6", default-features = false, path = "../metadata" }

trybuild = { version = "1.0.49", features = ["diff"] }
# Required for the doctest of `env_access::EnvAccess::instantiate_contract`
scale-info = { version = "1.0", default-features = false, features = ["derive"] }

[features]
Expand All @@ -43,3 +46,11 @@ std = [
"ink_lang_macro/std",
"scale/std",
]
show-codegen-docs = []

# Due to https://github.com/rust-lang/cargo/issues/6915 features that affect a dev-dependency
# currently can't be enabled by a parent crate, hence `["ink_env/ink-experimental-engine"]` does
# not work.
# After we switch to the new off-chain environment with https://github.com/paritytech/ink/issues/565
# we can remove the feature altogether.
ink-experimental-engine = []
68 changes: 68 additions & 0 deletions crates/lang/codegen/src/enforced_error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// Copyright 2018-2021 Parity Technologies (UK) Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use impl_serde::serialize as serde_hex;
use quote::format_ident;

/// Errors which may occur when forwarding a call is not allowed.
///
/// We insert markers for these errors in the generated contract code.
/// This is necessary since we can't check these errors at compile time
/// of the contract.
/// `cargo-contract` checks the contract code for these error markers
/// when building a contract and fails if it finds markers.
#[derive(scale::Encode, scale::Decode)]
pub enum EnforcedErrors {
/// The below error represents calling a `&mut self` message in a context that
/// only allows for `&self` messages. This may happen under certain circumstances
/// when ink! trait implementations are involved with long-hand calling notation.
#[codec(index = 1)]
CannotCallTraitMessage {
/// The trait that defines the called message.
trait_ident: String,
/// The name of the called message.
message_ident: String,
/// The selector of the called message.
message_selector: [u8; 4],
/// Is `true` if the `self` receiver of the ink! message is `&mut self`.
message_is_mut: bool,
},
}

impl EnforcedErrors {
/// Create the identifier of an enforced ink! compilation error.
fn into_ident(self) -> syn::Ident {
format_ident!(
"__ink_enforce_error_{}",
serde_hex::to_hex(&scale::Encode::encode(&self), false)
)
}

/// Creates an enforced linker error to signal that an invalid
/// implementation of an ink! trait message has been called.
pub fn cannot_call_trait_message(
trait_ident: &syn::Ident,
message_ident: &syn::Ident,
message_selector: ir::Selector,
message_is_mut: bool,
) -> syn::Ident {
Self::CannotCallTraitMessage {
trait_ident: trait_ident.to_string(),
message_ident: message_ident.to_string(),
message_selector: message_selector.to_bytes(),
message_is_mut,
}
.into_ident()
}
}
104 changes: 104 additions & 0 deletions crates/lang/codegen/src/generator/arg_list.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
// Copyright 2018-2021 Parity Technologies (UK) Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use heck::CamelCase;
use proc_macro2::{
Span,
TokenStream as TokenStream2,
};
use quote::{
format_ident,
quote,
quote_spanned,
};

/// Returns the associated output type for an ink! trait message.
pub fn output_ident(message_name: &syn::Ident) -> syn::Ident {
format_ident!("{}Output", message_name.to_string().to_camel_case())
}

/// Returns the sequence of artificial input parameter bindings for the message.
///
/// # Note
///
/// This returns `__ink_binding_N` for every message input where `N` is the number
/// of the input from first to last.
pub fn input_bindings(inputs: ir::InputsIter) -> Vec<syn::Ident> {
inputs
.enumerate()
.map(|(n, _)| format_ident!("__ink_binding_{}", n))
.collect::<Vec<_>>()
}

/// Returns the sequence of input types for the message.
pub fn input_types(inputs: ir::InputsIter) -> Vec<&syn::Type> {
inputs.map(|pat_type| &*pat_type.ty).collect::<Vec<_>>()
}

/// Returns a tuple type representing the types yielded by the input types.
pub fn input_types_tuple(inputs: ir::InputsIter) -> TokenStream2 {
let input_types = input_types(inputs);
if input_types.len() != 1 {
// Pack all types into a tuple if they are not exactly 1.
// This results in `()` for zero input types.
quote! { ( #( #input_types ),* ) }
} else {
// Return the single type without turning it into a tuple.
quote! { #( #input_types )* }
}
}

/// Returns a tuple expression representing the bindings yielded by the inputs.
pub fn input_bindings_tuple(inputs: ir::InputsIter) -> TokenStream2 {
let input_bindings = input_bindings(inputs);
match input_bindings.len() {
0 => quote! { _ },
1 => quote! { #( #input_bindings ),* },
_ => quote! { ( #( #input_bindings ),* ) },
}
}

/// Builds up the `ink_env::call::utils::ArgumentList` type structure for the given types.
pub fn generate_argument_list<'b, Args>(args: Args) -> TokenStream2
where
Args: IntoIterator<Item = &'b syn::Type>,
<Args as IntoIterator>::IntoIter: Iterator,
{
use syn::spanned::Spanned as _;
args.into_iter().fold(
quote! { ::ink_env::call::utils::EmptyArgumentList },
|rest, arg| {
let span = arg.span();
quote_spanned!(span=>
::ink_env::call::utils::ArgumentList<::ink_env::call::utils::Argument<#arg>, #rest>
)
}
)
}

/// Generates code to uniquely identify a trait by its unique ID given only its identifier.
///
/// # Note
///
/// As with all Rust macros identifiers can shadow each other so the given identifier
/// needs to be valid for the scope in which the returned code is generated.
pub fn generate_reference_to_trait_info(
span: Span,
trait_path: &syn::Path,
) -> TokenStream2 {
quote_spanned!(span=>
<::ink_lang::reflect::TraitDefinitionRegistry<Environment>
as #trait_path>::__ink_TraitInfo
)
}
Loading

0 comments on commit d87fc87

Please sign in to comment.