Skip to content

Commit

Permalink
Merge pull request #1635 from multiversx/unmanaged-fix
Browse files Browse the repository at this point in the history
TypeAbi Unmanaged improvements
  • Loading branch information
andrei-marinica authored May 20, 2024
2 parents d2a30ba + cc41380 commit fa616d3
Show file tree
Hide file tree
Showing 10 changed files with 54 additions and 24 deletions.
2 changes: 1 addition & 1 deletion framework/base/src/abi/type_abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use alloc::{format, string::ToString, vec::Vec};
///
/// Will be automatically implemented for struct ad enum types via the `#[type_abi]` annotation.
pub trait TypeAbi: TypeAbiFrom<Self> {
type Unmanaged: TypeAbiFrom<Self>;
type Unmanaged;

fn type_names() -> TypeNames {
TypeNames {
Expand Down
26 changes: 15 additions & 11 deletions framework/base/src/abi/type_abi_impl_basic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ impl TypeAbi for () {
impl<T, U> TypeAbiFrom<&U> for &T where T: TypeAbiFrom<U> {}

impl<T: TypeAbi> TypeAbi for &T {
type Unmanaged = Self;
type Unmanaged = T::Unmanaged;

fn type_name() -> TypeName {
T::type_name()
Expand Down Expand Up @@ -58,7 +58,7 @@ impl<T: TypeAbi> TypeAbi for Box<T> {
impl<T, U> TypeAbiFrom<&[T]> for &[U] where T: TypeAbiFrom<U> {}

impl<T: TypeAbi> TypeAbi for &[T] {
type Unmanaged = Self;
type Unmanaged = Vec<T::Unmanaged>;

fn type_name() -> TypeName {
let t_name = T::type_name();
Expand All @@ -84,7 +84,7 @@ impl<T: TypeAbi> TypeAbi for &[T] {
impl<T, U> TypeAbiFrom<Vec<T>> for Vec<U> where T: TypeAbiFrom<U> {}

impl<T: TypeAbi> TypeAbi for Vec<T> {
type Unmanaged = Self;
type Unmanaged = Vec<T::Unmanaged>;

fn type_name() -> TypeName {
<&[T]>::type_name()
Expand Down Expand Up @@ -209,6 +209,7 @@ type_abi_name_only!(i64, "i64");

type_abi_name_only!(core::num::NonZeroUsize, "NonZeroUsize");
type_abi_name_only!(bool, "bool");
type_abi_name_only!(f64, "f64");

// Unsigned integer types: the contract can return a smaller capacity result and and we can interpret it as a larger capacity type.

Expand Down Expand Up @@ -244,10 +245,13 @@ impl TypeAbiFrom<i8> for isize {}

impl TypeAbiFrom<i8> for i16 {}

impl<T, U> TypeAbiFrom<Option<T>> for Option<U> where T: TypeAbiFrom<U> {}
impl<T, U> TypeAbiFrom<Option<U>> for Option<T> where T: TypeAbiFrom<U> {}

impl<T: TypeAbi> TypeAbi for Option<T> {
type Unmanaged = Self;
impl<T> TypeAbi for Option<T>
where
T: TypeAbi,
{
type Unmanaged = Option<T::Unmanaged>;

fn type_name() -> TypeName {
format!("Option<{}>", T::type_name())
Expand All @@ -262,10 +266,10 @@ impl<T: TypeAbi> TypeAbi for Option<T> {
}
}

impl<T, U, E> TypeAbiFrom<Result<T, E>> for Result<U, E> where T: TypeAbiFrom<U> {}
impl<T: TypeAbi, E> TypeAbiFrom<Self> for Result<T, E> {}

impl<T: TypeAbi, E> TypeAbi for Result<T, E> {
type Unmanaged = Self;
type Unmanaged = Result<T::Unmanaged, E>;

fn type_name() -> TypeName {
T::type_name()
Expand Down Expand Up @@ -301,7 +305,7 @@ macro_rules! tuple_impls {
where
$($name: TypeAbi,)+
{
type Unmanaged = Self;
type Unmanaged = ($($name::Unmanaged,)+);

fn type_name() -> TypeName {
let mut repr = TypeName::from("tuple<");
Expand Down Expand Up @@ -356,10 +360,10 @@ tuple_impls! {
16 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13 14 T14 15 T15)
}

impl<T, U, const N: usize> TypeAbiFrom<[T; N]> for [U; N] where T: TypeAbiFrom<U> {}
impl<T, U, const N: usize> TypeAbiFrom<[U; N]> for [T; N] where T: TypeAbiFrom<U> {}

impl<T: TypeAbi, const N: usize> TypeAbi for [T; N] {
type Unmanaged = Self;
type Unmanaged = [T::Unmanaged; N];

fn type_name() -> TypeName {
let mut repr = TypeName::from("array");
Expand Down
6 changes: 3 additions & 3 deletions framework/base/src/abi/type_abi_impl_codec_multi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ where

#[cfg(feature = "alloc")]
impl<T: TypeAbi> TypeAbi for crate::codec::multi_types::MultiValueVec<T> {
type Unmanaged = Self;
type Unmanaged = crate::codec::multi_types::MultiValueVec<T::Unmanaged>;

fn type_name() -> TypeName {
super::type_name_variadic::<T>()
Expand Down Expand Up @@ -52,10 +52,10 @@ impl TypeAbi for IgnoreValue {
}
}

impl<T, U> TypeAbiFrom<OptionalValue<T>> for OptionalValue<U> where T: TypeAbiFrom<U> {}
impl<T, U> TypeAbiFrom<OptionalValue<U>> for OptionalValue<T> where T: TypeAbiFrom<U> {}

impl<T: TypeAbi> TypeAbi for OptionalValue<T> {
type Unmanaged = Self;
type Unmanaged = OptionalValue<T::Unmanaged>;

fn type_name() -> TypeName {
super::type_name_optional::<T>()
Expand Down
2 changes: 1 addition & 1 deletion framework/base/src/storage/mappers/single_value_mapper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ where
SA: StorageMapperApi,
T: TopEncode + TopDecode + TypeAbi,
{
type Unmanaged = Self;
type Unmanaged = T::Unmanaged;

fn type_name() -> TypeName {
T::type_name()
Expand Down
17 changes: 17 additions & 0 deletions framework/base/src/types/heap/arg_buffer.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use crate::{
abi::{TypeAbiFrom, TypeName},
api::ManagedTypeApi,
codec::TopEncodeOutput,
proxy_imports::TypeAbi,
types::{heap::BoxedBytes, ManagedArgBuffer},
};
use alloc::vec::Vec;
Expand Down Expand Up @@ -111,6 +113,21 @@ impl Clone for ArgBuffer {
}
}

impl TypeAbiFrom<Self> for ArgBuffer {}

impl TypeAbi for ArgBuffer {
type Unmanaged = Self;

/// It is semantically equivalent to any list of `T`.
fn type_name() -> TypeName {
<&[Vec<u8>] as TypeAbi>::type_name()
}

fn type_name_rust() -> TypeName {
"ArgBuffer".into()
}
}

impl TopEncodeOutput for &mut ArgBuffer {
type NestedBuffer = Vec<u8>;

Expand Down
7 changes: 6 additions & 1 deletion framework/base/src/types/heap/boxed_bytes.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
use alloc::{alloc::{alloc, Layout, realloc}, boxed::Box, vec, vec::Vec};
use alloc::{
alloc::{alloc, realloc, Layout},
boxed::Box,
vec,
vec::Vec,
};

use crate::{
abi::{TypeAbi, TypeAbiFrom, TypeName},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,10 @@ where
M: ManagedTypeApi,
T: TypeAbi,
{
#[cfg(feature = "alloc")]
type Unmanaged = MultiValueVec<T::Unmanaged>;

#[cfg(not(feature = "alloc"))]
type Unmanaged = Self;

fn type_name() -> TypeName {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,10 @@ where
M: ManagedTypeApi,
T: ManagedVecItem,
{
#[cfg(feature = "alloc")]
type Unmanaged = multiversx_sc_codec::multi_types::MultiValueVec<T::Unmanaged>;

#[cfg(not(feature = "alloc"))]
type Unmanaged = Self;

fn type_name() -> TypeName {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ impl<const N: usize> ManagedVecItemPayloadAdd<ManagedVecItemEmptyPayload>
}

/// Replaces a const generic expression.
///
///
/// Remove once const generic expressions are stabilized in Rust.
macro_rules! payload_add {
($dec1:expr, $dec2:expr, $result_add:expr) => {
Expand Down
8 changes: 2 additions & 6 deletions tools/payload-macro-generator/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const MAX_X: usize = 48;
const MAX_Y: usize = 128;

/// Generates the payload_add! macros in the ManagedVecItem implem,entation.
///
///
/// TODO: remove once generic const expressions are stabilized in Rust.
fn main() -> io::Result<()> {
let mut file = File::create("output.rs")?;
Expand All @@ -17,11 +17,7 @@ fn main() -> io::Result<()> {
for x in MIN..=MAX_X {
for y in MIN..=MAX_Y {
let sum = x + y;
writeln!(
file,
"payload_add!({}usize, {}usize, {}usize);",
x, y, sum
)?;
writeln!(file, "payload_add!({}usize, {}usize, {}usize);", x, y, sum)?;
}
}

Expand Down

0 comments on commit fa616d3

Please sign in to comment.