diff --git a/compiler/gen_llvm/src/llvm/build.rs b/compiler/gen_llvm/src/llvm/build.rs index 7fb646d4f4..9ca24e1739 100644 --- a/compiler/gen_llvm/src/llvm/build.rs +++ b/compiler/gen_llvm/src/llvm/build.rs @@ -3600,11 +3600,14 @@ fn expose_function_to_host_help_c_abi_v2<'a, 'ctx, 'env>( let param_types = Vec::from_iter_in(roc_function.get_type().get_param_types(), env.arena); - // drop the "return pointer" if it exists on the roc function - // and the c function does not return via pointer - let param_types = match (&roc_return, &cc_return) { - (RocReturn::ByPointer, CCReturn::Return) => ¶m_types[1..], - _ => ¶m_types, + let (params, param_types) = match (&roc_return, &cc_return) { + // Drop the "return pointer" if it exists on the roc function + // and the c function does not return via pointer + (RocReturn::ByPointer, CCReturn::Return) => (¶ms[..], ¶m_types[1..]), + // Drop the return pointer the other way, if the C function returns by pointer but Roc + // doesn't + (RocReturn::Return, CCReturn::ByPointer) => (¶ms[1..], ¶m_types[..]), + _ => (¶ms[..], ¶m_types[..]), }; debug_assert_eq!(params.len(), param_types.len()); diff --git a/compiler/load/tests/test_load.rs b/compiler/load/tests/test_load.rs index 4634f65d75..8b4abdd7ca 100644 --- a/compiler/load/tests/test_load.rs +++ b/compiler/load/tests/test_load.rs @@ -648,4 +648,42 @@ mod test_load { Ok(_) => unreachable!("we expect failure here"), } } + + #[test] + // See https://github.com/rtfeldman/roc/issues/2413 + fn platform_exposes_main_return_by_pointer_issue() { + let modules = vec![ + ( + "platform/Package-Config.roc", + indoc!( + r#" + platform "examples/hello-world" + requires {} { main : { content: Str, other: Str } } + exposes [] + packages {} + imports [] + provides [ mainForHost ] + + mainForHost : { content: Str, other: Str } + mainForHost = main + "# + ), + ), + ( + "Main", + indoc!( + r#" + app "hello-world" + packages { pf: "platform" } + imports [] + provides [ main ] to pf + + main = { content: "Hello, World!\n", other: "" } + "# + ), + ), + ]; + + assert!(multiple_modules(modules).is_ok()); + } }