Repository: metacall/core (language: rust)

Issue:
Segmentation fault + memory leaks in rust loader
## 🐛 Bug Report
When running with valgrind (because sanitizer is not giving me stack traces):

`LOADER_LIBRARY_PATH=/metacall-core/build LOADER_SCRIPT_PATH=/metacall-core/build/scripts CONFIGURATION_PATH=/metacall-core/build/configurations/global.json SERIAL_LIBRARY_PATH=/metacall-core/build DETOUR_LIBRARY_PATH=/metacall-core/build PORT_LIBRARY_PATH=/metacall-core/build RUST_BACKTRACE=1 RUST_LOG=INFO  valgrind --leak-check=full --tool=memcheck ./metacall-rust-testd`

I get this: 
[valgrind.txt](https://github.com/metacall/core/files/9155135/valgrind.txt)

I have added this line: https://github.com/metacall/core/blob/434836813427bdfc8adb4c376662aaa9997eaf1c/source/loaders/rs_loader/rust/src/lifecycle/destroy.rs#L9

It is necessary, it reduces the amount of leaks but generates a segmentation fault. It must be reviewed.

@MediosZ


Discussion / hints:
Here's the stack trace.
```
34: ==2034831==ERROR: AddressSanitizer: SEGV on unknown address 0x7f2afd9fc150 (pc 0x7f2afd0c009b bp 0x7fff25932f10 sp 0x7fff25932dd0 T0)
34: ==2034831==The signal is caused by a READ memory access.
34:     #0 0x7f2afd0c009a in alloc::sync::Arc$LT$T$GT$::get_mut_unchecked::hc0eedccc5e2fbb5e /rustc/532d2b14c05f9bc20b2d27cbb5f4550d28343a36/library/alloc/src/sync.rs
34:     #1 0x7f2afd0c0c13 in alloc::sync::Arc$LT$T$GT$::drop_slow::hcdddc1345ba6db32 /rustc/532d2b14c05f9bc20b2d27cbb5f4550d28343a36/library/alloc/src/sync.rs:1079
34:     #2 0x7f2afd039a82 in _$LT$alloc..sync..Arc$LT$T$GT$$u20$as$u20$core..ops..drop..Drop$GT$::drop::h6d67c4b2876df72f /rustc/532d2b14c05f9bc20b2d27cbb5f4550d28343a36/library/alloc/src/sync.rs:1640
34:     #3 0x7f2afcff19ea in core::ptr::drop_in_place$LT$alloc..sync..Arc$LT$dyn$u20$core..ops..function..Fn$LT$$LP$alloc..vec..Vec$LT$$BP$mut$u20$core..ffi..c_void$GT$$C$$RP$$GT$$u2b$Output$u20$$u3d$$u20$core..result..Result$LT$$BP$mut$u20$core..ffi..c_void$C$i32$GT$$u2b$core..marker..Send$u2b$core..marker..Sync$GT$$GT$::h6d25a359803075a7 /rustc/532d2b14c05f9bc20b2d27cbb5f4550d28343a36/library/core/src/ptr/mod.rs:188
34:     #4 0x7f2afd0237ba in core::ptr::drop_in_place$LT$compiler..wrapper..class..NormalFunction$GT$::hab1a96f39247ec72 /rustc/532d2b14c05f9bc20b2d27cbb5f4550d28343a36/library/core/src/ptr/mod.rs:188
34:     #5 0x7f2afd0309f9 in core::ptr::drop_in_place$LT$alloc..boxed..Box$LT$compiler..wrapper..class..NormalFunction$GT$$GT$::haf6fcd7285a0efc5 /rustc/532d2b14c05f9bc20b2d27cbb5f4550d28343a36/library/core/src/ptr/mod.rs:188
34:     #6 0x7f2afcfc867d in core::mem::drop::h97464a221d5106ed /rustc/532d2b14c05f9bc20b2d27cbb5f4550d28343a36/library/core/src/mem/mod.rs:909
34:     #7 0x7f2afd2124e3 in function_singleton_destroy compiler/src/api/function.rs:66
34:     #8 0x7f2b01f42778 in function_destroy /home/tric/codebase/metacall/source/reflect/source/reflect_function.c:669
34:     #9 0x7f2b01f58aeb in value_type_destroy /home/tric/codebase/metacall/source/reflect/source/reflect_value_type.c:665
34:     #10 0x7f2b01f50cab in scope_destroy_cb_iterate /home/tric/codebase/metacall/source/reflect/source/reflect_scope.c:603
34:     #11 0x7f2b01f24522 in set_iterate /home/tric/codebase/metacall/source/adt/source/adt_set.c:410
34:     #12 0x7f2b01f53f27 in scope_destroy /home/tric/codebase/metacall/source/reflect/source/reflect_scope.c:615
34:     #13 0x7f2b01f5459a in context_destroy /home/tric/codebase/metacall/source/reflect/source/reflect_context.c:104
34:     #14 0x7f2b01f61ee1 in loader_impl_destroy_handle /home/tric/codebase/metacall/source/loader/source/loader_impl.c:596
34:     #15 0x7f2b01f6275b in loader_impl_destroy_handle_map_cb_iterate /home/tric/codebase/metacall/source/loader/source/loader_impl.c:1279
34:     #16 0x7f2b01f24522 in set_iterate /home/tric/codebase/metacall/source/adt/source/adt_set.c:410
34:     #17 0x7f2b01f686f4 in loader_impl_destroy_objects /home/tric/codebase/metacall/source/loader/source/loader_impl.c:1315
34:     #18 0x7f2b01f686f4 in loader_impl_destroy_objects /home/tric/codebase/metacall/source/loader/source/loader_impl.c:1303
34:     #19 0x7f2b01f6019a in loader_unload_children /home/tric/codebase/metacall/source/loader/source/loader.c:710
34:     #20 0x7f2afd0ffc0a in compiler::api::loader_lifecycle_unload_children::h4ff3680358197aea compiler/src/api/mod.rs:131
34:     #21 0x7f2afcf77816 in rs_loader_impl_destroy src/lifecycle/destroy.rs:9
34:     #22 0x7f2b01f68ad2 in loader_impl_destroy /home/tric/codebase/metacall/source/loader/source/loader_impl.c:1357
34:     #23 0x7f2b01f68c50 in loader_impl_destroy_dtor /home/tric/codebase/metacall/source/loader/source/loader_impl.c:1342
34:     #24 0x7f2b01f397d1 in plugin_destroy_delayed /home/tric/codebase/metacall/source/plugin/source/plugin_impl.c:110
34:     #25 0x7f2b01f600ba in loader_unload_children /home/tric/codebase/metacall/source/loader/source/loader.c:691
34:     #26 0x7f2b01f605dd in loader_destroy /home/tric/codebase/metacall/source/loader/source/loader.c:737
34:     #27 0x7f2b01f77aa0 in metacall_destroy /home/tric/codebase/metacall/source/metacall/source/metacall.c:2155
34:     #28 0x5647a60b138a in metacall_rust_test_DefaultConstructor_Test::TestBody() /home/tric/codebase/metacall/source/tests/metacall_rust_test/source/metacall_rust_test.cpp:172
```

This may be  caused by this line.
https://github.com/metacall/core/blob/434836813427bdfc8adb4c376662aaa9997eaf1c/source/loaders/rs_loader/rust/compiler/src/api/function.rs#L66

The whole log: 
[rust_test.log](https://github.com/metacall/core/files/9156667/rust_test.log)

After comment out those two lines, the seg fault goes away but there are still leaks.
the log:
[rust_test.log](https://github.com/metacall/core/files/9157037/rust_test.log)


Fix patch:
diff --git a/source/loaders/rs_loader/rust/compiler/src/api/class.rs b/source/loaders/rs_loader/rust/compiler/src/api/class.rs
index 9acf5afa0..2c81e33e6 100644
--- a/source/loaders/rs_loader/rust/compiler/src/api/class.rs
+++ b/source/loaders/rs_loader/rust/compiler/src/api/class.rs
@@ -119,11 +119,12 @@ extern "C" fn class_singleton_static_await(
 
 #[no_mangle]
 extern "C" fn class_singleton_destroy(_klass: OpaqueType, class_impl: OpaqueType) {
-    // unsafe {
-    //     let class_impl_ptr = class_impl as *mut class::Class;
-    //     let class = Box::from_raw(class_impl_ptr);
-    //     drop(class);
-    // }
+    if !class_impl.is_null() {
+        unsafe {
+            let class = Box::from_raw(class_impl as *mut class::Class);
+            drop(class);
+        }
+    }
     println!("class destroy");
 }
 
@@ -239,6 +240,17 @@ pub fn register_class(class_registration: ClassRegistration) {
                 );
             };
         }
+        else {
+            let ret = CString::new("Null")
+            .expect("Failed to convert return type to C string");
+
+            unsafe {
+                signature_set_return(
+                    s,
+                    loader_impl_type(class_registration.loader_impl, ret.as_ptr()),
+                );
+            };
+        }
         for (idx, param) in method.args.iter().enumerate() {
             let name = CString::new(param.name.clone())
                 .expect("Failed to convert function parameter name to C string");
@@ -283,6 +295,17 @@ pub fn register_class(class_registration: ClassRegistration) {
                 );
             };
         }
+        else {
+            let ret = CString::new("Null")
+            .expect("Failed to convert return type to C string");
+
+            unsafe {
+                signature_set_return(
+                    s,
+                    loader_impl_type(class_registration.loader_impl, ret.as_ptr()),
+                );
+            };
+        }
         for (idx, param) in method.args.iter().enumerate() {
             let name = CString::new(param.name.clone())
                 .expect("Failed to convert function parameter name to C string");
diff --git a/source/loaders/rs_loader/rust/compiler/src/api/function.rs b/source/loaders/rs_loader/rust/compiler/src/api/function.rs
index 6d8d31d6c..84162bb14 100644
--- a/source/loaders/rs_loader/rust/compiler/src/api/function.rs
+++ b/source/loaders/rs_loader/rust/compiler/src/api/function.rs
@@ -31,11 +31,6 @@ extern "C" fn function_singleton_invoke(
     size: usize,
 ) -> OpaqueType {
     unsafe {
-        // let func_ptr = Box::from_raw(func_impl as *mut unsafe fn());
-        // let func: fn(OpaqueTypeList, usize) -> OpaqueType = std::mem::transmute_copy(&*func_ptr);
-        // let result = func(args_p, size);
-        // std::mem::forget(func_ptr);
-        // result
         let args = std::slice::from_raw_parts(args_p, size).to_vec();
         let nf = Box::from_raw(func_impl as *mut class::NormalFunction);
         let res = nf.invoke(args).unwrap();
@@ -62,10 +57,12 @@ extern "C" fn function_singleton_await(
 #[no_mangle]
 extern "C" fn function_singleton_destroy(_func: OpaqueType, func_impl: OpaqueType) {
     // comment out this due to the seg fault
-    // unsafe {
-    //     let func_ptr = Box::from_raw(func_impl as *mut class::NormalFunction);
-    //     drop(func_ptr);
-    // }
+    if !func_impl.is_null() {
+        unsafe {
+            let func_ptr = Box::from_raw(func_impl as *mut class::NormalFunction);
+            drop(func_ptr);
+        }
+    }
 }
 
 #[no_mangle]
@@ -115,6 +112,16 @@ pub fn register_function(function_registration: FunctionRegistration) {
     if let Some(ret) = function_registration.ret {
         let ret = CString::new(ret).expect("Failed to convert return type to C string");
 
+        unsafe {
+            signature_set_return(
+                s,
+                loader_impl_type(function_registration.loader_impl, ret.as_ptr()),
+            );
+        };
+    } 
+    else {
+        let ret = CString::new("Null").expect("Failed to convert return type to C string");
+
         unsafe {
             signature_set_return(
                 s,
diff --git a/source/loaders/rs_loader/rust/compiler/src/api/mod.rs b/source/loaders/rs_loader/rust/compiler/src/api/mod.rs
index 1f425db3e..eb89aa299 100644
--- a/source/loaders/rs_loader/rust/compiler/src/api/mod.rs
+++ b/source/loaders/rs_loader/rust/compiler/src/api/mod.rs
@@ -17,10 +17,14 @@ pub use class::{class_singleton, register_class, ClassCreate, ClassRegistration}
 
 pub struct LoaderLifecycleState {
     pub execution_paths: Vec<PathBuf>,
+    pub destroy_list: Vec<super::DlopenLibrary>,
 }
 impl LoaderLifecycleState {
     pub fn new(execution_paths: Vec<PathBuf>) -> LoaderLifecycleState {
-        LoaderLifecycleState { execution_paths }
+        LoaderLifecycleState {
+            execution_paths,
+            destroy_list: vec![],
+        }
     }
 }
 extern "C" {
diff --git a/source/loaders/rs_loader/rust/compiler/src/api/object.rs b/source/loaders/rs_loader/rust/compiler/src/api/object.rs
index 6314f8a6c..b2d46c787 100644
--- a/source/loaders/rs_loader/rust/compiler/src/api/object.rs
+++ b/source/loaders/rs_loader/rust/compiler/src/api/object.rs
@@ -123,11 +123,12 @@ extern "C" fn object_singleton_method_await(
 }
 #[no_mangle]
 extern "C" fn object_singleton_destructor(_object: OpaqueType, object_impl: OpaqueType) -> c_int {
-    // unsafe {
-    //     let object_impl_ptr = object_impl as *mut Object;
-    //     let object = Box::from_raw(object_impl_ptr);
-    //     drop(object);
-    // }
+    if !object_impl.is_null() {
+        unsafe {
+            let object = Box::from_raw(object_impl as *mut Object);
+            drop(object);
+        }
+    }
     println!("destruct object");
     0
 }
diff --git a/source/loaders/rs_loader/rust/compiler/src/file.rs b/source/loaders/rs_loader/rust/compiler/src/file.rs
index 1a884bd76..b75a049e3 100644
--- a/source/loaders/rs_loader/rust/compiler/src/file.rs
+++ b/source/loaders/rs_loader/rust/compiler/src/file.rs
@@ -8,7 +8,7 @@ use crate::{registrator, DlopenLibrary};
 pub struct FileRegistration {
     pub path_to_file: PathBuf,
     pub state: CompilerState,
-    pub dlopen: DlopenLibrary,
+    pub dlopen: Option<DlopenLibrary>,
 }
 impl FileRegistration {
     pub fn new(path_to_file: PathBuf) -> Result<FileRegistration, RegistrationError> {
@@ -31,13 +31,17 @@ impl FileRegistration {
         Ok(FileRegistration {
             path_to_file,
             state,
-            dlopen,
+            dlopen: Some(dlopen),
         })
     }
 
     pub fn discover(&self, loader_impl: *mut c_void, ctx: *mut c_void) -> Result<(), String> {
-        registrator::register(&self.state, &self.dlopen, loader_impl, ctx);
-
-        Ok(())
+        match &self.dlopen {
+            Some(dl) => {
+                registrator::register(&self.state, &dl, loader_impl, ctx);
+                Ok(())
+            }
+            None => Err(String::from("The dlopen_lib is None")),
+        }
     }
 }
diff --git a/source/loaders/rs_loader/rust/compiler/src/memory.rs b/source/loaders/rs_loader/rust/compiler/src/memory.rs
index e92dd2d01..b89edb562 100644
--- a/source/loaders/rs_loader/rust/compiler/src/memory.rs
+++ b/source/loaders/rs_loader/rust/compiler/src/memory.rs
@@ -8,7 +8,7 @@ use crate::{registrator, DlopenLibrary};
 pub struct MemoryRegistration {
     pub name: String,
     pub state: CompilerState,
-    pub dlopen: DlopenLibrary,
+    pub dlopen: Option<DlopenLibrary>,
 }
 impl MemoryRegistration {
     pub fn new(name: String, code: String) -> Result<MemoryRegistration, RegistrationError> {
@@ -40,13 +40,17 @@ impl MemoryRegistration {
         Ok(MemoryRegistration {
             name,
             state,
-            dlopen,
+            dlopen: Some(dlopen),
         })
     }
 
     pub fn discover(&self, loader_impl: *mut c_void, ctx: *mut c_void) -> Result<(), String> {
-        registrator::register(&self.state, &self.dlopen, loader_impl, ctx);
-
-        Ok(())
+        match &self.dlopen {
+            Some(dl) => {
+                registrator::register(&self.state, &dl, loader_impl, ctx);
+                Ok(())
+            }
+            None => Err(String::from("The dlopen_lib is None")),
+        }
     }
 }
diff --git a/source/loaders/rs_loader/rust/compiler/src/package.rs b/source/loaders/rs_loader/rust/compiler/src/package.rs
index bd901a89b..d50344c5f 100644
--- a/source/loaders/rs_loader/rust/compiler/src/package.rs
+++ b/source/loaders/rs_loader/rust/compiler/src/package.rs
@@ -6,7 +6,7 @@ use std::{ffi::c_void, path::PathBuf};
 pub struct PackageRegistration {
     pub path_to_file: PathBuf,
     pub state: CompilerState,
-    pub dlopen: DlopenLibrary,
+    pub dlopen: Option<DlopenLibrary>,
 }
 
 impl PackageRegistration {
@@ -30,13 +30,17 @@ impl PackageRegistration {
         Ok(PackageRegistration {
             path_to_file,
             state,
-            dlopen,
+            dlopen: Some(dlopen),
         })
     }
 
     pub fn discover(&self, loader_impl: *mut c_void, ctx: *mut c_void) -> Result<(), String> {
-        registrator::register(&self.state, &self.dlopen, loader_impl, ctx);
-
-        Ok(())
+        match &self.dlopen {
+            Some(dl) => {
+                registrator::register(&self.state, &dl, loader_impl, ctx);
+                Ok(())
+            }
+            None => Err(String::from("The dlopen_lib is None")),
+        }
     }
 }
diff --git a/source/loaders/rs_loader/rust/compiler/src/wrapper/class.rs b/source/loaders/rs_loader/rust/compiler/src/wrapper/class.rs
index 32c74cbb4..152f1d2c4 100644
--- a/source/loaders/rs_loader/rust/compiler/src/wrapper/class.rs
+++ b/source/loaders/rs_loader/rust/compiler/src/wrapper/class.rs
@@ -35,6 +35,7 @@ extern "C" {
     fn metacall_value_create_string(st: *const c_char, ln: usize) -> *mut c_void;
     fn metacall_value_create_array(values: *const *mut c_void, size: usize) -> *mut c_void;
     fn metacall_value_create_map(tuples: *const *mut c_void, size: usize) -> *mut c_void;
+    fn metacall_value_create_null() -> *mut c_void;
 }
 
 type Attributes = HashMap<&'static str, AttributeGetter>;
@@ -454,7 +455,7 @@ pub trait ToMetaResult {
 
 impl ToMetaResult for () {
     fn to_meta_result(self) -> Result<MetacallValue> {
-        Ok(unsafe { metacall_value_create_int(0) })
+        Ok(unsafe { metacall_value_create_null() })
     }
 }
 
diff --git a/source/loaders/rs_loader/rust/src/lifecycle/clear.rs b/source/loaders/rs_loader/rust/src/lifecycle/clear.rs
index ca7f297b6..2625bc8ea 100644
--- a/source/loaders/rs_loader/rust/src/lifecycle/clear.rs
+++ b/source/loaders/rs_loader/rust/src/lifecycle/clear.rs
@@ -1,9 +1,29 @@
-use crate::{c_int, c_void};
 use super::loader::LoadingMethod;
+use crate::{c_int, c_void};
+
+use compiler::api;
 
 #[no_mangle]
-pub extern "C" fn rs_loader_impl_clear(_loader_impl: *mut c_void, handle: *mut c_void) -> c_int {
-    let handle_shared_objects = unsafe { Box::from_raw(handle as *mut Vec<LoadingMethod>) };
-    drop(handle_shared_objects);
+pub extern "C" fn rs_loader_impl_clear(loader_impl: *mut c_void, handle: *mut c_void) -> c_int {
+    let loader_lifecycle_state = unsafe {
+        api::get_loader_lifecycle_state(loader_impl)
+            .as_mut()
+            .expect("Unable to get loader state")
+    };
+    unsafe {
+        let methods = Box::from_raw(handle as *mut Vec<LoadingMethod>);
+        for loading_method in *methods {
+            match loading_method.consume_dlib() {
+                Ok(lib) => {
+                    // extend the lifetime of library
+                    loader_lifecycle_state.destroy_list.push(lib);
+                }
+                Err(err) => {
+                    eprintln!("{}", err);
+                    return 1 as c_int;
+                }
+            }
+        }
+    }
     0 as c_int
 }
diff --git a/source/loaders/rs_loader/rust/src/lifecycle/destroy.rs b/source/loaders/rs_loader/rust/src/lifecycle/destroy.rs
index 92b2f904e..5773a1476 100644
--- a/source/loaders/rs_loader/rust/src/lifecycle/destroy.rs
+++ b/source/loaders/rs_loader/rust/src/lifecycle/destroy.rs
@@ -9,7 +9,9 @@ pub extern "C" fn rs_loader_impl_destroy(loader_impl: *mut c_void) -> c_int {
     api::loader_lifecycle_unload_children(loader_impl);
 
     unsafe {
-        loader_lifecycle_state.drop_in_place();
+        let state = Box::from_raw(loader_lifecycle_state);
+        // drop the state, including dlibs.
+        drop(state);
     }
 
     0 as c_int
diff --git a/source/loaders/rs_loader/rust/src/lifecycle/initialize.rs b/source/loaders/rs_loader/rust/src/lifecycle/initialize.rs
index cdc23680d..69ee7f8bc 100644
--- a/source/loaders/rs_loader/rust/src/lifecycle/initialize.rs
+++ b/source/loaders/rs_loader/rust/src/lifecycle/initialize.rs
@@ -114,6 +114,13 @@ pub extern "C" fn rs_loader_impl_initialize(
         0 as c_int as *mut c_void,
         0 as c_int as *mut c_void,
     );
+    api::define_type(
+        loader_impl,
+        "Null",
+        PrimitiveMetacallProtocolTypes::Null,
+        0 as c_int as *mut c_void,
+        0 as c_int as *mut c_void,
+    );
     // Register initialization
     api::loader_lifecycle_register(loader_impl);
 
diff --git a/source/loaders/rs_loader/rust/src/lifecycle/loader.rs b/source/loaders/rs_loader/rust/src/lifecycle/loader.rs
index 679d56128..60dbe295b 100644
--- a/source/loaders/rs_loader/rust/src/lifecycle/loader.rs
+++ b/source/loaders/rs_loader/rust/src/lifecycle/loader.rs
@@ -15,6 +15,34 @@ pub enum LoadingMethod {
     Memory(MemoryRegistration),
 }
 
+impl LoadingMethod {
+    pub fn consume_dlib(self) -> Result<compiler::DlopenLibrary, String> {
+        match self {
+            Self::File(FileRegistration { mut dlopen, .. }) => match dlopen {
+                Some(_) => {
+                    let dl = std::mem::replace(&mut dlopen, None);
+                    Ok(dl.expect("Unexpected: dlopen is None"))
+                }
+                None => Err(String::from("consume_dlib was called more than once")),
+            },
+            Self::Package(PackageRegistration { mut dlopen, .. }) => match dlopen {
+                Some(_) => {
+                    let dl = std::mem::replace(&mut dlopen, None);
+                    Ok(dl.expect("Unexpected: dlopen is None"))
+                }
+                None => Err(String::from("consume_dlib was called more than once")),
+            },
+            Self::Memory(MemoryRegistration { mut dlopen, .. }) => match dlopen {
+                Some(_) => {
+                    let dl = std::mem::replace(&mut dlopen, None);
+                    Ok(dl.expect("Unexpected: dlopen is None"))
+                }
+                None => Err(String::from("consume_dlib was called more than once")),
+            },
+        }
+    }
+}
+
 // Trait aliasing
 pub trait OnPathBufClosure:
     Fn(PathBuf, fn(error: String) -> *mut c_void) -> Result<LoadingMethod, *mut c_void>
diff --git a/source/scripts/rust/basic/source/basic.rs b/source/scripts/rust/basic/source/basic.rs
index 706b0a4e6..fde0ea796 100644
--- a/source/scripts/rust/basic/source/basic.rs
+++ b/source/scripts/rust/basic/source/basic.rs
@@ -1,4 +1,7 @@
 use std::collections::HashMap;
+use std::fs::File;
+use std::io::Write;
+use std::env;
 
 pub fn add(num_1: i32, num_2: i32) -> i32 {
     num_1 + num_2
@@ -13,7 +16,9 @@ pub fn add_float(num_1: f32, num_2: f32) -> f32 {
 }
 
 pub fn run() {
-    println!("Hello World")
+    let dir = env::temp_dir();
+    let mut f = File::create(dir.join("hello.txt")).unwrap();
+    f.write(b"Hello metacall");
 }
 
 // pub fn add_vec(vec: &mut Vec<i32>) -> i32 {


Test patch:
diff --git a/source/tests/metacall_rust_load_from_package_test/source/metacall_rust_load_from_package_test.cpp b/source/tests/metacall_rust_load_from_package_test/source/metacall_rust_load_from_package_test.cpp
index 75faaf97f..067305426 100644
--- a/source/tests/metacall_rust_load_from_package_test/source/metacall_rust_load_from_package_test.cpp
+++ b/source/tests/metacall_rust_load_from_package_test/source/metacall_rust_load_from_package_test.cpp
@@ -79,7 +79,7 @@ TEST_F(metacall_rust_load_from_mem_test, DefaultConstructor)
 
 	{
 		void *ret = metacall("run");
-		EXPECT_EQ((int)0, (int)metacall_value_to_int(ret));
+		EXPECT_EQ((void *)NULL, (void *)metacall_value_to_null(ret));
 		metacall_value_destroy(ret);
 	}
 
diff --git a/source/tests/metacall_rust_test/source/metacall_rust_test.cpp b/source/tests/metacall_rust_test/source/metacall_rust_test.cpp
index e64fa5e3e..3f65ce30e 100644
--- a/source/tests/metacall_rust_test/source/metacall_rust_test.cpp
+++ b/source/tests/metacall_rust_test/source/metacall_rust_test.cpp
@@ -80,7 +80,7 @@ TEST_F(metacall_rust_test, DefaultConstructor)
 
 	{
 		void *ret = metacall("run");
-		EXPECT_EQ((int)0, (int)metacall_value_to_int(ret));
+		EXPECT_EQ((void *)NULL, (void *)metacall_value_to_null(ret));
 		metacall_value_destroy(ret);
 	}
 
diff --git a/source/tests/sanitizer/lsan.supp b/source/tests/sanitizer/lsan.supp
index 5b76962fc..bbacb3857 100644
--- a/source/tests/sanitizer/lsan.supp
+++ b/source/tests/sanitizer/lsan.supp
@@ -34,3 +34,7 @@ leak:libruby*
 #
 leak:libcoreclr*
 leak:libicuuc*
+#
+# Rust
+#
+leak:libLLVM*
\ No newline at end of file