-
Notifications
You must be signed in to change notification settings - Fork 4
feat: model interior borrows for refcell #786
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
8a72058
9f82eec
c2d6862
28cf9d5
93cad6f
fa24d9b
ede664c
55237eb
21f5034
537b584
c525218
f270fe8
c25f259
2093f58
a313ead
1057a44
d3d93ca
8d95126
46e791a
4b3ba64
e319042
96dc111
e4b482c
430dd93
6cb7e3f
e5f30b7
0a78bae
d0c1793
08389d0
2e1aeb1
1b24944
5ca54b5
4683341
a8b3258
f1c3005
d94197b
d45a24a
69a4efd
eb83742
b13b312
d3b81e1
716dc16
3450bc8
1efd5f7
cd57064
0a16989
0b07a30
d57f4f3
541edd4
193bef5
8358db0
3b3ef6a
9cc3eaf
8a77758
8e75511
4f9fcd9
83c924c
54ceab5
00e2df2
55f9281
5c6128e
61c8c69
8cc88c4
82392e7
cca1452
76a081e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,121 @@ | ||
| //! Minimal dual-AccountInfo harness for MIR semantics tests. | ||
|
|
||
| use std::cell::{Ref, RefCell, RefMut}; | ||
|
|
||
| trait MiniPack: Copy { | ||
| const LEN: usize; | ||
| fn pack_into_slice(self, dst: &mut [u8]); | ||
| fn unpack_unchecked(src: &[u8]) -> Self | ||
| where | ||
| Self: Sized; | ||
| } | ||
|
|
||
| #[derive(Clone, Copy, Debug, PartialEq, Eq)] | ||
| struct MiniMint { | ||
| decimals: u8, | ||
| supply: u64, | ||
| } | ||
|
|
||
| impl MiniPack for MiniMint { | ||
| const LEN: usize = 9; | ||
|
|
||
| fn pack_into_slice(self, dst: &mut [u8]) { | ||
| assert_eq!(dst.len(), Self::LEN); | ||
| dst[0] = self.decimals; | ||
| dst[1..].copy_from_slice(&self.supply.to_le_bytes()); | ||
| } | ||
|
|
||
| fn unpack_unchecked(src: &[u8]) -> Self { | ||
| let mut supply = [0_u8; 8]; | ||
| supply.copy_from_slice(&src[1..]); | ||
| Self { | ||
| decimals: src[0], | ||
| supply: u64::from_le_bytes(supply), | ||
| } | ||
| } | ||
| } | ||
|
|
||
| #[derive(Clone, Copy, Debug, PartialEq, Eq)] | ||
| struct MiniTokenAccount { | ||
| owner: [u8; 8], | ||
| amount: u64, | ||
| status: u8, | ||
| } | ||
|
|
||
| impl MiniPack for MiniTokenAccount { | ||
| const LEN: usize = 17; | ||
|
|
||
| fn pack_into_slice(self, dst: &mut [u8]) { | ||
| assert_eq!(dst.len(), Self::LEN); | ||
| dst[0..8].copy_from_slice(&self.owner); | ||
| dst[8..16].copy_from_slice(&self.amount.to_le_bytes()); | ||
| dst[16] = self.status; | ||
| } | ||
|
|
||
| fn unpack_unchecked(src: &[u8]) -> Self { | ||
| let mut owner = [0_u8; 8]; | ||
| owner.copy_from_slice(&src[0..8]); | ||
| let mut amount = [0_u8; 8]; | ||
| amount.copy_from_slice(&src[8..16]); | ||
| Self { | ||
| owner, | ||
| amount: u64::from_le_bytes(amount), | ||
| status: src[16], | ||
| } | ||
| } | ||
| } | ||
|
|
||
| pub struct AccountInfo<'a> { | ||
| data: RefCell<&'a mut [u8]>, | ||
| } | ||
|
|
||
| impl<'a> AccountInfo<'a> { | ||
| pub fn new(data: &'a mut [u8]) -> Self { | ||
| Self { | ||
| data: RefCell::new(data), | ||
| } | ||
| } | ||
|
|
||
| pub fn borrow_data(&self) -> Ref<'_, [u8]> { | ||
| Ref::map(self.data.borrow(), |slice| &**slice) | ||
| } | ||
|
|
||
| pub fn borrow_mut_data(&self) -> RefMut<'_, [u8]> { | ||
| RefMut::map(self.data.borrow_mut(), |slice| &mut **slice) | ||
| } | ||
| } | ||
|
|
||
| #[no_mangle] | ||
| pub fn dual_account_demo(account_info: &AccountInfo, mint_info: &AccountInfo) -> bool { | ||
| let account_read = account_info.borrow_data(); | ||
| let mint_read = mint_info.borrow_data(); | ||
| let _ = MiniTokenAccount::unpack_unchecked(&account_read); | ||
| let _ = MiniMint::unpack_unchecked(&mint_read); | ||
| drop(account_read); | ||
| drop(mint_read); | ||
|
|
||
| let mut account_write = account_info.borrow_mut_data(); | ||
| let mut mint_write = mint_info.borrow_mut_data(); | ||
| MiniTokenAccount { | ||
| owner: *b"demoacct", | ||
| amount: 123, | ||
| status: 1, | ||
| } | ||
| .pack_into_slice(&mut account_write); | ||
| MiniMint { | ||
| decimals: 9, | ||
| supply: 500, | ||
| } | ||
| .pack_into_slice(&mut mint_write); | ||
|
||
|
|
||
| true | ||
| } | ||
|
|
||
| fn main() { | ||
| let mut account_bytes = [0_u8; MiniTokenAccount::LEN]; | ||
| let mut mint_bytes = [0_u8; MiniMint::LEN]; | ||
| let account = AccountInfo::new(&mut account_bytes); | ||
| let mint = AccountInfo::new(&mut mint_bytes); | ||
| let result = dual_account_demo(&account, &mint); | ||
| assert!(result); | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the reason for adding no mangle? Is that necessary?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added #[no_mangle] so we get a stable symbol name when driving this fixture through the new dylib-based integration test. The harness loads the compiled library and calls lib.get(b"dual_account_demo"); without the attribute that symbol is emitted with the usual Rust mangling (e.g. _RNvNt…dual_account_demo) so the lookup fails. Keeping the unmangled name lets the test resolve the entrypoint consistently. I tried leaning on the mangled name from the metadata, but the crate hash makes that brittle between builds, so the attribute ended up being the reliable fix.