diff --git a/compiler/gen/src/llvm/build.rs b/compiler/gen/src/llvm/build.rs index da7812491a..197ede8e3c 100644 --- a/compiler/gen/src/llvm/build.rs +++ b/compiler/gen/src/llvm/build.rs @@ -15,7 +15,6 @@ use crate::llvm::refcounting::{ }; use bumpalo::collections::Vec; use bumpalo::Bump; -use either; use inkwell::basic_block::BasicBlock; use inkwell::builder::Builder; use inkwell::context::Context; @@ -1941,7 +1940,7 @@ where let catch_block = context.append_basic_block(parent, "catch_block"); let cont_block = context.append_basic_block(parent, "cont_block"); - let result_alloca = builder.build_alloca(call_result_type.clone(), "result"); + let result_alloca = builder.build_alloca(call_result_type, "result"); // invoke instead of call, so that we can catch any exeptions thrown in Roc code let call_result = { @@ -2147,6 +2146,11 @@ pub fn build_proc_header<'a, 'ctx, 'env>( Layout::Closure(arguments, closure, result) => { build_closure_caller(env, &fn_name, *name, arguments, closure, result) } + Layout::FunctionPointer(_arguments, _result) => { + // TODO should this be considered a closure of size 0? + // or do we let the host call it directly? + // then we have no RocCallResult wrapping though + } _ => { // TODO } @@ -2215,12 +2219,11 @@ pub fn build_closure_caller<'a, 'ctx, 'env>( let function_pointer_type = { let function_layout = ClosureLayout::extend_function_layout(arena, arguments, closure.clone(), result); - let basic_type = basic_type_from_layout(arena, context, &function_layout, env.ptr_bytes); // this is already a (function) pointer type - basic_type + basic_type_from_layout(arena, context, &function_layout, env.ptr_bytes) }; - argument_types.push(function_pointer_type.into()); + argument_types.push(function_pointer_type); let closure_argument_type = { let basic_type = basic_type_from_layout( diff --git a/compiler/mono/src/ir.rs b/compiler/mono/src/ir.rs index 3ff462ff8f..af4fce5653 100644 --- a/compiler/mono/src/ir.rs +++ b/compiler/mono/src/ir.rs @@ -1793,9 +1793,7 @@ fn introduce_solved_type_to_subs<'a>(env: &mut Env<'a, '_>, solved_type: &Solved env.subs.extend_by(variables_introduced as usize); - let result = insert_type_into_subs(env.subs, &normal_type); - - result + insert_type_into_subs(env.subs, &normal_type) } fn specialize_solved_type<'a>( diff --git a/examples/closure/platform/src/lib.rs b/examples/closure/platform/src/lib.rs index 11002134c0..4d23d9522c 100644 --- a/examples/closure/platform/src/lib.rs +++ b/examples/closure/platform/src/lib.rs @@ -1,9 +1,7 @@ use roc_std::alloca; +use roc_std::RocCallResult; use std::alloc::Layout; -use std::ffi::CString; -use std::os::raw::c_char; use std::time::SystemTime; -use RocCallResult::*; extern "C" { #[link_name = "makeClosure_1_exposed"] @@ -53,10 +51,10 @@ pub fn rust_main() -> isize { make_closure(buffer); - let output = &*(buffer as *mut RocCallResult<((), ())>); + let output = &*(buffer as *mut RocCallResult<()>); match output.into() { - Ok((_, _)) => { + Ok(()) => { let function_pointer = { // this is a pointer to the location where the function pointer is stored // we pass just the function pointer @@ -89,45 +87,3 @@ pub fn rust_main() -> isize { // Exit code 0 } - -#[repr(u64)] -pub enum RocCallResult { - Success(T), - Failure(*mut c_char), -} - -impl Into> for RocCallResult { - fn into(self) -> Result { - match self { - Success(value) => Ok(value), - Failure(failure) => Err({ - let raw = unsafe { CString::from_raw(failure) }; - - let result = format!("{:?}", raw); - - // make sure rust does not try to free the Roc string - std::mem::forget(raw); - - result - }), - } - } -} - -impl Into> for &RocCallResult { - fn into(self) -> Result { - match self { - Success(value) => Ok(*value), - Failure(failure) => Err({ - let raw = unsafe { CString::from_raw(*failure) }; - - let result = format!("{:?}", raw); - - // make sure rust does not try to free the Roc string - std::mem::forget(raw); - - result - }), - } - } -} diff --git a/roc_std/src/lib.rs b/roc_std/src/lib.rs index 10e93386de..a501f7f26c 100644 --- a/roc_std/src/lib.rs +++ b/roc_std/src/lib.rs @@ -464,3 +464,30 @@ impl Into> for RocCallResult { } } } + +impl<'a, T: Sized + Copy> Into> for &'a RocCallResult { + fn into(self) -> Result { + use RocCallResult::*; + + match self { + Success(value) => Ok(*value), + Failure(failure) => Err({ + let msg = unsafe { + let mut null_byte_index = 0; + loop { + if *failure.offset(null_byte_index) == 0 { + break; + } + null_byte_index += 1; + } + + let bytes = core::slice::from_raw_parts(*failure, null_byte_index as usize); + + core::str::from_utf8_unchecked(bytes) + }; + + msg + }), + } + } +}