From 108fa150e40bed060fce5d15da2a14b2536970ca Mon Sep 17 00:00:00 2001 From: mansiverma897993 Date: Fri, 19 Jun 2026 14:37:19 +0530 Subject: [PATCH] fix: resolve panic when UserType appears as struct member Signed-off-by: mansiverma897993 --- src/sema/types.rs | 2 ++ tests/solana_tests/structs.rs | 37 +++++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/src/sema/types.rs b/src/sema/types.rs index e9ecfbb6f..03c1ba71b 100644 --- a/src/sema/types.rs +++ b/src/sema/types.rs @@ -1633,6 +1633,7 @@ impl Type { .max() .unwrap_or(1), // All fields had infinite size, so we just pretend the alignment is one Type::InternalFunction { .. } => ns.target.ptr_size().into(), + Type::UserType(no) => ns.user_types[*no].ty.align_of(ns), _ => 1, } } @@ -1835,6 +1836,7 @@ impl Type { Type::Mapping(..) => BigInt::from(4), Type::Ref(ty) | Type::StorageRef(_, ty) => ty.storage_align(ns), Type::Unresolved => BigInt::one(), + Type::UserType(no) => ns.user_types[*no].ty.storage_align(ns), _ => unimplemented!(), }; diff --git a/tests/solana_tests/structs.rs b/tests/solana_tests/structs.rs index 2199402df..290249955 100644 --- a/tests/solana_tests/structs.rs +++ b/tests/solana_tests/structs.rs @@ -78,3 +78,40 @@ fn struct_as_reference() { ]) ); } + +#[test] +fn user_defined_type_in_struct() { + let mut vm = build_solidity( + r#" + type C is address; + struct S { C c; } + contract T { + S s; + function set_c(C c) public { + s.c = c; + } + function get_c() public view returns (C) { + return s.c; + } + } + "#, + ); + + let data_account = vm.initialize_data_account(); + vm.function("new") + .accounts(vec![("dataAccount", data_account)]) + .call(); + + let address = [0x42; 32]; + vm.function("set_c") + .arguments(&[BorshToken::Address(address)]) + .accounts(vec![("dataAccount", data_account)]) + .call(); + + let res = vm + .function("get_c") + .accounts(vec![("dataAccount", data_account)]) + .call() + .unwrap(); + assert_eq!(res, BorshToken::Address(address)); +}