stellar / rs-soroban-env

Rust environment for Soroban contracts.
Apache License 2.0
59 stars 40 forks source link

Tuples of tnteger types (i32, i128) are not ref convertible into Val #1327

Open leighmcculloch opened 6 months ago

leighmcculloch commented 6 months ago

What version are you using?

20.0.0

What did you do?

let v: soroban_sdk::Val = (&0i128,).into_val(&env);

What did you expect to see?

Compiled, because all types are supposed to be value convertible 0i128.into_val(&env), ref convertible (&0i128).into_val(&env), and tuple convertible `(&0i128,).into_val(&env).

What did you see instead?

Compile error:

error[E0277]: the trait bound `soroban_sdk::Val: TryFromVal<Env, &i128>` is not satisfied
  --> src/test.rs:25:50
   |
25 |     let v: soroban_sdk::Val = (&0i128,).into_val(&env);
   |                                         -------- ^^^^ the trait `TryFromVal<Env, &i128>` is not implemented for `soroban_sdk::Val`
   |                                         |
   |                                         required by a bound introduced by this call
   |
   = help: the following other types implement trait `TryFromVal<E, V>`:
             <soroban_sdk::Val as TryFromVal<Env, State>>
             <soroban_sdk::Val as TryFromVal<Env, soroban_sdk::Vec<T>>>
             <soroban_sdk::Val as TryFromVal<Env, soroban_sdk::Address>>
             <soroban_sdk::Val as TryFromVal<Env, soroban_sdk::Symbol>>
             <soroban_sdk::Val as TryFromVal<Env, soroban_sdk::auth::Context>>
             <soroban_sdk::Val as TryFromVal<Env, ContractContext>>
             <soroban_sdk::Val as TryFromVal<Env, CreateContractHostFnContext>>
             <soroban_sdk::Val as TryFromVal<Env, soroban_sdk::auth::ContractExecutable>>
           and 110 others
   = note: required for `&i128` to implement `TryIntoVal<Env, soroban_sdk::Val>`
   = note: required for `soroban_sdk::Val` to implement `TryFromVal<Env, (&i128,)>`
   = note: required for `soroban_sdk::Val` to implement `FromVal<Env, (&i128,)>`
   = note: required for `(&i128,)` to implement `IntoVal<Env, soroban_sdk::Val>`
anupsdf commented 6 months ago

Looks like just SDK change to implement the trait and call env convert.rs

jayz22 commented 6 months ago

The TryFromVal are all implemented for the types themselves (@anupsdf's finding above), not references. So doing let v: Val = (0i128,).into_val(&env); without the & sign will work. @leighmcculloch is there a reason why it needs to work with the references?

leighmcculloch commented 6 months ago

@jayz22 I've tried to always provide both so that we can have a ref of something and still get a Val out of it.

If you have a ref of something and first need to get an owned value of it, that's tricky, because then you need it to impl ToOwned or Clone, and types may not implement those things.