@@ -2164,6 +2164,34 @@ fn assign_args_to_params_kw(
2164
2164
Ok ( ( ) )
2165
2165
}
2166
2166
2167
+ fn coerce_result_type (
2168
+ result : Result < Option < KclValue > , KclError > ,
2169
+ function_expression : NodeRef < ' _ , FunctionExpression > ,
2170
+ exec_state : & mut ExecState ,
2171
+ ) -> Result < Option < KclValue > , KclError > {
2172
+ if let Ok ( Some ( val) ) = result {
2173
+ if let Some ( ret_ty) = & function_expression. return_type {
2174
+ let ty = RuntimeType :: from_parsed ( ret_ty. inner . clone ( ) , exec_state, ret_ty. as_source_range ( ) )
2175
+ . map_err ( |e| KclError :: Semantic ( e. into ( ) ) ) ?;
2176
+ let val = val. coerce ( & ty, exec_state) . map_err ( |_| {
2177
+ KclError :: Semantic ( KclErrorDetails {
2178
+ message : format ! (
2179
+ "This function requires its result to be of type `{}`, but found {}" ,
2180
+ ty. human_friendly_type( ) ,
2181
+ val. human_friendly_type( ) ,
2182
+ ) ,
2183
+ source_ranges : ret_ty. as_source_ranges ( ) ,
2184
+ } )
2185
+ } ) ?;
2186
+ Ok ( Some ( val) )
2187
+ } else {
2188
+ Ok ( Some ( val) )
2189
+ }
2190
+ } else {
2191
+ result
2192
+ }
2193
+ }
2194
+
2167
2195
async fn call_user_defined_function (
2168
2196
args : Vec < Arg > ,
2169
2197
memory : EnvironmentRef ,
@@ -2184,13 +2212,16 @@ async fn call_user_defined_function(
2184
2212
let result = ctx
2185
2213
. exec_block ( & function_expression. body , exec_state, BodyType :: Block )
2186
2214
. await ;
2187
- let result = result. map ( |_| {
2215
+ let mut result = result. map ( |_| {
2188
2216
exec_state
2189
2217
. stack ( )
2190
2218
. get ( memory:: RETURN_NAME , function_expression. as_source_range ( ) )
2191
2219
. ok ( )
2192
2220
. cloned ( )
2193
2221
} ) ;
2222
+
2223
+ result = coerce_result_type ( result, function_expression, exec_state) ;
2224
+
2194
2225
// Restore the previous memory.
2195
2226
exec_state. mut_stack ( ) . pop_env ( ) ;
2196
2227
@@ -2218,13 +2249,16 @@ async fn call_user_defined_function_kw(
2218
2249
let result = ctx
2219
2250
. exec_block ( & function_expression. body , exec_state, BodyType :: Block )
2220
2251
. await ;
2221
- let result = result. map ( |_| {
2252
+ let mut result = result. map ( |_| {
2222
2253
exec_state
2223
2254
. stack ( )
2224
2255
. get ( memory:: RETURN_NAME , function_expression. as_source_range ( ) )
2225
2256
. ok ( )
2226
2257
. cloned ( )
2227
2258
} ) ;
2259
+
2260
+ result = coerce_result_type ( result, function_expression, exec_state) ;
2261
+
2228
2262
// Restore the previous memory.
2229
2263
exec_state. mut_stack ( ) . pop_env ( ) ;
2230
2264
0 commit comments