@@ -287,6 +287,12 @@ fn (mut c Checker) comptime_for(mut node ast.ComptimeFor) {
287287 }
288288 has_different_types := fields.len > 1
289289 && ! fields.all (c.check_basic (it .typ, fields[0 ].typ))
290+ if fields.len == 0 {
291+ // force eval `node.stmts` to set their types
292+ fields << ast.StructField{
293+ typ: ast.error_type
294+ }
295+ }
290296 for field in fields {
291297 c.push_new_comptime_info ()
292298 prev_inside_x_matches_type := c.inside_x_matches_type
@@ -302,15 +308,17 @@ fn (mut c Checker) comptime_for(mut node ast.ComptimeFor) {
302308 c.comptime.has_different_types = has_different_types
303309 c.stmts (mut node.stmts)
304310
305- unwrapped_expr_type := c.unwrap_generic (field.typ)
306- tsym := c.table.sym (unwrapped_expr_type)
307- c.markused_comptimefor (mut node, unwrapped_expr_type)
308- if tsym.kind == .array_fixed {
309- info := tsym.info as ast.ArrayFixed
310- if ! info.is_fn_ret {
311- // for dumping fixed array we must register the fixed array struct to return from function
312- c.table.find_or_register_array_fixed (info.elem_type, info.size,
313- info.size_expr, true )
311+ if field.typ != ast.no_type {
312+ unwrapped_expr_type := c.unwrap_generic (field.typ)
313+ tsym := c.table.sym (unwrapped_expr_type)
314+ c.markused_comptimefor (mut node, unwrapped_expr_type)
315+ if tsym.kind == .array_fixed {
316+ info := tsym.info as ast.ArrayFixed
317+ if ! info.is_fn_ret {
318+ // for dumping fixed array we must register the fixed array struct to return from function
319+ c.table.find_or_register_array_fixed (info.elem_type, info.size,
320+ info.size_expr, true )
321+ }
314322 }
315323 }
316324 c.inside_x_matches_type = prev_inside_x_matches_type
@@ -344,16 +352,22 @@ fn (mut c Checker) comptime_for(mut node ast.ComptimeFor) {
344352 return
345353 }
346354 } else if node.kind == .methods {
347- methods := sym.get_methods ()
355+ mut methods := sym.get_methods ()
356+ if methods.len == 0 {
357+ // force eval `node.stmts` to set their types
358+ methods << ast.Fn{}
359+ }
348360 for method in methods {
349361 c.push_new_comptime_info ()
350362 c.comptime.inside_comptime_for = true
351363 c.comptime.comptime_for_method = unsafe { & method }
352364 c.comptime.comptime_for_method_var = node.val_var
353365 c.comptime.comptime_for_method_ret_type = method.return_type
354366 c.type_resolver.update_ct_type ('${node.val_var} .return_type' , method.return_type)
355- for j, arg in method.params[1 ..] {
356- c.type_resolver.update_ct_type ('${node.val_var} .args[${j} ].typ' , arg.typ.idx ())
367+ if method.params.len > 0 {
368+ for j, arg in method.params[1 ..] {
369+ c.type_resolver.update_ct_type ('${node.val_var} .args[${j} ].typ' , arg.typ.idx ())
370+ }
357371 }
358372 c.stmts (mut node.stmts)
359373 c.pop_comptime_info ()
@@ -366,7 +380,11 @@ fn (mut c Checker) comptime_for(mut node ast.ComptimeFor) {
366380 }
367381
368382 func := if sym.info is ast.FnType { & sym.info.func } else { c.comptime.comptime_for_method }
369- params := if func.is_method { func.params[1 ..] } else { func.params }
383+ mut params := if func.is_method { func.params[1 ..] } else { func.params }
384+ if params.len == 0 {
385+ // force eval `node.stmts` to set their types
386+ params << ast.Param{}
387+ }
370388 // example: fn (mut d MyStruct) add(x int, y int) string
371389 // `d` is params[0], `x` is params[1], `y` is params[2]
372390 // so we at least has one param (`d`) for method
@@ -379,7 +397,11 @@ fn (mut c Checker) comptime_for(mut node ast.ComptimeFor) {
379397 c.pop_comptime_info ()
380398 }
381399 } else if node.kind == .attributes {
382- attrs := c.table.get_attrs (sym)
400+ mut attrs := c.table.get_attrs (sym)
401+ if attrs.len == 0 {
402+ // force eval `node.stmts` to set their types
403+ attrs << ast.Attr{}
404+ }
383405 for attr in attrs {
384406 c.push_new_comptime_info ()
385407 c.comptime.inside_comptime_for = true
0 commit comments