@@ -205,7 +205,40 @@ fn (mut g Gen) if_expr(node ast.IfExpr) {
205205 } else {
206206 node.typ
207207 }
208- mut styp := g.styp (node_typ)
208+ // For generic functions, if the if-expression's type was set to a concrete type
209+ // by the checker but we're generating a different generic instance, we need to
210+ // use the correct concrete type from cur_concrete_types
211+ resolved_typ := if g.cur_fn != unsafe { nil } && g.cur_fn.generic_names.len > 0
212+ && g.cur_concrete_types.len > 0 {
213+ // Try to unwrap generic, and if that doesn't work, check if we should use
214+ // the function's return type
215+ unwrapped := g.unwrap_generic (node_typ)
216+ if unwrapped == node_typ && g.cur_fn.return_type.has_flag (.generic) {
217+ // The node type didn't unwrap, but the function return type is generic
218+ // Get the unwrapped function return type for this instance
219+ mut fn_ret_typ := g.unwrap_generic (g.cur_fn.return_type)
220+ if g.inside_or_block {
221+ fn_ret_typ = fn_ret_typ.clear_option_and_result ()
222+ }
223+ // Check if the function return type directly matches one of the concrete types
224+ // If it does, the if expression type should also match that concrete type
225+ fn_ret_is_direct_generic := g.cur_concrete_types.any (it == fn_ret_typ)
226+ if fn_ret_is_direct_generic && node_typ != fn_ret_typ {
227+ // The function returns T directly, and node_typ doesn't match the current T
228+ // This means node_typ is stale from another instance
229+ fn_ret_typ
230+ } else {
231+ // Either the function return type is wrapped (like !T or []T),
232+ // or node_typ is correct for this instance
233+ unwrapped
234+ }
235+ } else {
236+ unwrapped
237+ }
238+ } else {
239+ g.unwrap_generic (node_typ)
240+ }
241+ mut styp := g.styp (resolved_typ)
209242 if (g.inside_if_option || node_typ.has_flag (.option)) && ! g.inside_or_block {
210243 raw_state = g.inside_if_option
211244 if node.typ != ast.void_type {
@@ -237,7 +270,7 @@ fn (mut g Gen) if_expr(node ast.IfExpr) {
237270 if tmp != '' {
238271 if node.typ == ast.void_type && g.last_if_option_type != 0 {
239272 // nested if on return stmt
240- g.write2 (g.styp (g.last_if_option_type), ' ' )
273+ g.write2 (g.styp (g.unwrap_generic (g. last_if_option_type) ), ' ' )
241274 } else {
242275 g.write ('${styp } ' )
243276 }
0 commit comments