cgen: fix `for in` with mutable structs (#12368)
							parent
							
								
									639cbfa0d1
								
							
						
					
					
						commit
						3fdbfca202
					
				| 
						 | 
					@ -2165,7 +2165,11 @@ fn (mut g Gen) for_in_stmt(node ast.ForInStmt) {
 | 
				
			||||||
		g.writeln('\tif (${t_var}.state != 0) break;')
 | 
							g.writeln('\tif (${t_var}.state != 0) break;')
 | 
				
			||||||
		val := if node.val_var in ['', '_'] { g.new_tmp_var() } else { node.val_var }
 | 
							val := if node.val_var in ['', '_'] { g.new_tmp_var() } else { node.val_var }
 | 
				
			||||||
		val_styp := g.typ(node.val_type)
 | 
							val_styp := g.typ(node.val_type)
 | 
				
			||||||
		g.writeln('\t$val_styp $val = *($val_styp*)${t_var}.data;')
 | 
							if node.val_is_mut {
 | 
				
			||||||
 | 
								g.writeln('\t$val_styp* $val = ($val_styp*)${t_var}.data;')
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								g.writeln('\t$val_styp $val = *($val_styp*)${t_var}.data;')
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		typ_str := g.table.type_to_str(node.cond_type)
 | 
							typ_str := g.table.type_to_str(node.cond_type)
 | 
				
			||||||
		g.error('for in: unhandled symbol `$node.cond` of type `$typ_str`', node.pos)
 | 
							g.error('for in: unhandled symbol `$node.cond` of type `$typ_str`', node.pos)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,45 @@
 | 
				
			||||||
 | 
					struct Struct {
 | 
				
			||||||
 | 
					mut:
 | 
				
			||||||
 | 
						array [][]int
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn (s Struct) rows() StructsRowIterator {
 | 
				
			||||||
 | 
						return StructsRowIterator{
 | 
				
			||||||
 | 
							array: s.array
 | 
				
			||||||
 | 
							position: 0
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct StructsRowIterator {
 | 
				
			||||||
 | 
						Struct
 | 
				
			||||||
 | 
					mut:
 | 
				
			||||||
 | 
						position int
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn (mut s StructsRowIterator) next() ?[]int {
 | 
				
			||||||
 | 
						if s.position >= s.array.len {
 | 
				
			||||||
 | 
							return error('out of range')
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer {
 | 
				
			||||||
 | 
							s.position++
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return s.array[s.position]
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn test_for_in_mut_struct_val() {
 | 
				
			||||||
 | 
						mut s := Struct{
 | 
				
			||||||
 | 
							array: [[1, 2, 3], [4, 5, 6]]
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						println(s)
 | 
				
			||||||
 | 
						mut si := s.rows()
 | 
				
			||||||
 | 
						println(si)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						mut rets := []string{}
 | 
				
			||||||
 | 
						for mut row in si {
 | 
				
			||||||
 | 
							println(row)
 | 
				
			||||||
 | 
							rets << '$row'
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						assert rets.len == 2
 | 
				
			||||||
 | 
						assert rets[0] == '[1, 2, 3]'
 | 
				
			||||||
 | 
						assert rets[1] == '[4, 5, 6]'
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Loading…
	
		Reference in New Issue