Skip to content

Commit

Permalink
Merge pull request #1644 from multiversx/diagnostics-on-unimplemented
Browse files Browse the repository at this point in the history
Unified syntax - better compile-time errors
  • Loading branch information
andrei-marinica authored May 24, 2024
2 parents 08ac2fa + 099e888 commit bf7db0b
Show file tree
Hide file tree
Showing 16 changed files with 121 additions and 7 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/actions-nightly.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
name: Contracts (nightly)
uses: multiversx/mx-sc-actions/.github/workflows/contracts.yml@v3.2.0
with:
rust-toolchain: nightly-2023-12-11
rust-toolchain: nightly-2024-05-22
path-to-sc-meta: framework/meta
enable-contracts-size-report: false
mx-scenario-go-version: v2.1.0-alpha
Expand Down
1 change: 1 addition & 0 deletions contracts/feature-tests/abi-tester/src/abi_test_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,5 +39,6 @@ pub struct AbiManagedVecItem {

#[type_abi]
pub struct OnlyShowsUpInEsdtAttr {
#[allow(dead_code)]
pub field: OnlyShowsUpAsNested10,
}
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ fn abi_tester_esdt_attr_abi_generated_ok() {

#[test]
fn check_multi_contract_config() {
let mut blockchain = ScenarioWorld::new();
let blockchain = ScenarioWorld::new();

let multi_contract_config = multiversx_sc_meta::multi_contract_config::<abi_tester::AbiProvider>(
blockchain.current_dir().as_path(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ pub struct ComposabilityInteract {
pub wallet_address: Address,
pub forw_queue_code: BytesValue,
pub vault_code: BytesValue,
#[allow(dead_code)]
pub state: State,
}

Expand Down
10 changes: 10 additions & 0 deletions framework/base/src/types/interaction/tx_data/tx_code_source.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@ where
{
}

#[diagnostic::on_unimplemented(
message = "Type `{Self}` cannot be used as code (does not implement `TxCodeValue<{Env}>`)",
label = "not a valid smart contract byte code",
note = "there are multiple ways to specify SC byte code, but `{Self}` is not one of them"
)]
pub trait TxCodeValue<Env>: AnnotatedValue<Env, ManagedBuffer<Env::Api>>
where
Env: TxEnv,
Expand All @@ -39,6 +44,11 @@ where
{
}

#[diagnostic::on_unimplemented(
message = "Type `{Self}` cannot be used as code source value (does not implement `TxFromSourceValue<{Env}>`)",
label = "not an address from where to copy the code",
note = "there are multiple ways to specify a code source address, but `{Self}` is not one of them"
)]
pub trait TxFromSourceValue<Env>: AnnotatedValue<Env, ManagedAddress<Env::Api>>
where
Env: TxEnv,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::{
api::{const_handles, CallTypeApi},
contract_base::SendRawWrapper,
contract_base::{ErrorHelper, SendRawWrapper},
types::{
interaction::callback_closure::CallbackClosureWithGas, CallbackClosure, ExplicitGas,
FunctionCall, ManagedBuffer, ManagedType, OriginalResultMarker, Tx, TxGas, TxGasValue,
Expand Down Expand Up @@ -143,6 +143,20 @@ where
GasValue: TxGasValue<TxScEnv<Api>>,
Callback: TxPromisesCallback<Api>,
{
/// Launches a transaction as an asynchronous promise (async v2 mechanism).
///
/// Several such transactions can be launched from a single transaction.
///
/// Must set:
/// - to
/// - gas
/// - a function call, ideally via a proxy.
///
/// Value-only promises are not supported.
///
/// Optionally, can add:
/// - any payment
/// - a promise callback, which also needs explicit gas for callback.
pub fn register_promise(self) {
let callback_name = self.result_handler.callback_name();
let mut cb_closure_args_serialized =
Expand Down Expand Up @@ -174,6 +188,65 @@ where
}
}

impl<Api, To, Payment, Callback> Tx<TxScEnv<Api>, (), To, Payment, (), FunctionCall<Api>, Callback>
where
Api: CallTypeApi,
To: TxToSpecified<TxScEnv<Api>>,
Payment: TxPayment<TxScEnv<Api>>,
Callback: TxPromisesCallback<Api>,
{
/// ## Incorrect call
///
/// Must set **gas** in order to call `register_promise`.
///
/// ## Safety
///
/// This version of the method must never be called. It is only here to provide a more readable error.
pub unsafe fn register_promise(self) {
ErrorHelper::<Api>::signal_error_with_message("register_promise requires explicit gas");
}
}

impl<Api, To, Payment, Callback> Tx<TxScEnv<Api>, (), To, Payment, (), (), Callback>
where
Api: CallTypeApi,
To: TxToSpecified<TxScEnv<Api>>,
Payment: TxPayment<TxScEnv<Api>>,
Callback: TxPromisesCallback<Api>,
{
/// ## Incorrect call
///
/// Must set **gas** and **function call** in order to call `register_promise`.
///
/// ## Safety
///
/// This version of the method must never be called. It is only here to provide a more readable error.
pub unsafe fn register_promise(self) {
ErrorHelper::<Api>::signal_error_with_message("register_promise requires explicit gas and function call");
}
}

impl<Api, To, Payment, GasValue, Callback>
Tx<TxScEnv<Api>, (), To, Payment, ExplicitGas<GasValue>, (), Callback>
where
Api: CallTypeApi,
To: TxToSpecified<TxScEnv<Api>>,
Payment: TxPayment<TxScEnv<Api>>,
GasValue: TxGasValue<TxScEnv<Api>>,
Callback: TxPromisesCallback<Api>,
{
/// ## Incorrect call
///
/// Must set **function call** in order to call `register_promise`.
///
/// ## Safety
///
/// This version of the method must never be called. It is only here to provide a more readable error.
pub unsafe fn register_promise(self) {
ErrorHelper::<Api>::signal_error_with_message("register_promise requires function call");
}
}

impl<Api, To, Payment, Gas, Callback>
Tx<TxScEnv<Api>, (), To, Payment, Gas, FunctionCall<Api>, Callback>
where
Expand Down
5 changes: 5 additions & 0 deletions framework/base/src/types/interaction/tx_from.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ where
/// Marks the non-empty sender of a transaction.
///
/// Enforces the reciipent to be explicitly specified.
#[diagnostic::on_unimplemented(
message = "Type `{Self}` cannot be used as a sender value (does not implement `TxFromSpecified<{Env}>`)",
label = "sender needs to be explicit",
note = "there are multiple ways to specify the sender value for a transaction, but `{Self}` is not one of them"
)]
pub trait TxFromSpecified<Env>:
TxFrom<Env> + AnnotatedValue<Env, ManagedAddress<Env::Api>>
where
Expand Down
6 changes: 6 additions & 0 deletions framework/base/src/types/interaction/tx_gas.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use crate::{
types::ManagedBuffer,
};

/// All typed that populate the gas field of a transaction need to implement this trait.
pub trait TxGas<Env>
where
Env: TxEnv,
Expand Down Expand Up @@ -32,6 +33,11 @@ where
}
}

#[diagnostic::on_unimplemented(
message = "Type `{Self}` cannot be used as gas value (does not implement `TxGasValue<{Env}>`)",
label = "not a valid value for gas",
note = "there are multiple ways to specify the gas value for a transaction, but `{Self}` is not one of them"
)]
pub trait TxGasValue<Env>: AnnotatedValue<Env, u64>
where
Env: TxEnv,
Expand Down
5 changes: 5 additions & 0 deletions framework/base/src/types/interaction/tx_payment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ use crate::{
use super::{AnnotatedValue, FunctionCall, TxEnv, TxFrom, TxToSpecified};

/// Describes a payment that is part of a transaction.
#[diagnostic::on_unimplemented(
message = "Type `{Self}` cannot be used as payment (does not implement `TxPayment<{Env}>`)",
label = "not a valid payment type",
note = "there are multiple ways to specify the transaction payment, but `{Self}` is not one of them"
)]
pub trait TxPayment<Env>
where
Env: TxEnv,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@ use crate::types::TxEnv;
/// Result handler list item.
///
/// It acts as a result handler that produces a single result.
#[diagnostic::on_unimplemented(
message = "Type `{Self}` cannot be used as a decoder result handler (does not implement `RHListItem<{Env}>`)",
label = "not a valid decoder result handler",
note = "there are multiple ways to specify the result handling, but `{Self}` is not one of them"
)]
pub trait RHListItem<Env, Original>
where
Env: TxEnv,
Expand Down
7 changes: 6 additions & 1 deletion framework/base/src/types/interaction/tx_to.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,12 @@ impl<Env> TxTo<Env> for () where Env: TxEnv {}

/// Marks the non-empty recipient of a transaction.
///
/// Enforces the reciipent to be explicitly specified.
/// Enforces the recipient to be explicitly specified.
#[diagnostic::on_unimplemented(
message = "Type `{Self}` cannot be used as recipient value (does not implement `TxToSpecified<{Env}>`)",
label = "recipient needs to be explicit",
note = "there are multiple ways to specify the recipient value for a transaction, but `{Self}` is not one of them"
)]
pub trait TxToSpecified<Env>: TxTo<Env> + AnnotatedValue<Env, ManagedAddress<Env::Api>>
where
Env: TxEnv,
Expand Down
1 change: 1 addition & 0 deletions framework/derive/src/model/contract_trait.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ pub struct ContractTrait {
/// It is possible to automatically implement a contract module for all contracts that use it indirectly.
/// The drawback is that the developer make sure multiple inheritance does not happen.
/// This feature is currently disabled.
#[allow(dead_code)]
pub auto_inheritance_modules: Vec<Supertrait>,

pub methods: Vec<Method>,
Expand Down
1 change: 1 addition & 0 deletions framework/derive/src/model/supertrait.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ pub type ModulePath = Punctuated<syn::PathSegment, PathSep>;
#[derive(Clone, Debug)]
pub struct Supertrait {
pub full_path: syn::Path,
#[allow(dead_code)]
pub trait_name: syn::PathSegment,
pub module_path: ModulePath,
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ const TYPES_FROM_FRAMEWORK: &[&str] = &[
];

pub struct ProxyGenerator<'a> {
#[allow(dead_code)]
pub meta_config: &'a MetaConfig,
pub file: Option<&'a mut dyn std::io::Write>,
pub proxy_config: &'a ProxyConfigSerde,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ const CARGO_HOME: &str = env!("CARGO_HOME");

#[derive(Clone, Debug)]
pub struct ScenarioGoRelease {
#[allow(dead_code)]
pub tag_name: String,
pub download_url: String,
}
Expand Down
5 changes: 2 additions & 3 deletions framework/scenario/tests/scenarios_self_test.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
use multiversx_sc_scenario::*;

// These tests don't really test any contract, but the testing framework itslef.
// These tests don't really test any contract, but the testing framework itself.

fn world() -> ScenarioWorld {
let mut blockchain = ScenarioWorld::new();
blockchain
ScenarioWorld::new()
}

/// Checks that externalSteps work fine.
Expand Down

0 comments on commit bf7db0b

Please sign in to comment.