ink_codegen/
enforced_error.rs

1// Copyright (C) Use Ink (UK) Ltd.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use impl_serde::serialize as serde_hex;
16use quote::format_ident;
17
18/// Errors which may occur when forwarding a call is not allowed.
19///
20/// We insert markers for these errors in the generated contract code.
21/// This is necessary since we can't check these errors at compile time
22/// of the contract.
23/// `cargo-contract` checks the contract code for these error markers
24/// when building a contract and fails if it finds markers.
25#[derive(scale::Encode, scale::Decode)]
26pub enum EnforcedErrors {
27    /// The below error represents calling a `&mut self` message in a context that
28    /// only allows for `&self` messages. This may happen under certain circumstances
29    /// when ink! trait implementations are involved with long-hand calling notation.
30    #[codec(index = 1)]
31    CannotCallTraitMessage {
32        /// The trait that defines the called message.
33        trait_ident: String,
34        /// The name of the called message.
35        message_ident: String,
36        /// The selector of the called message.
37        message_selector: [u8; 4],
38        /// Is `true` if the `self` receiver of the ink! message is `&mut self`.
39        message_is_mut: bool,
40    },
41}
42
43impl EnforcedErrors {
44    /// Create the identifier of an enforced ink! compilation error.
45    fn into_ident(self) -> syn::Ident {
46        format_ident!(
47            "__ink_enforce_error_{}",
48            serde_hex::to_hex(&scale::Encode::encode(&self), false)
49        )
50    }
51
52    /// Creates an enforced linker error to signal that an invalid
53    /// implementation of an ink! trait message has been called.
54    pub fn cannot_call_trait_message(
55        trait_ident: &syn::Ident,
56        message_ident: &syn::Ident,
57        message_selector: ir::Selector,
58        message_is_mut: bool,
59    ) -> syn::Ident {
60        Self::CannotCallTraitMessage {
61            trait_ident: trait_ident.to_string(),
62            message_ident: message_ident.to_string(),
63            message_selector: message_selector.to_bytes(),
64            message_is_mut,
65        }
66        .into_ident()
67    }
68}