checker/cgen: auto initialize `shared` elements of structs (#9669)
							parent
							
								
									3241611871
								
							
						
					
					
						commit
						954c436d28
					
				|  | @ -646,7 +646,8 @@ pub fn (mut c Checker) struct_init(mut struct_init ast.StructInit) ast.Type { | |||
| 				if field.has_default_expr || field.name in inited_fields { | ||||
| 					continue | ||||
| 				} | ||||
| 				if field.typ.is_ptr() && !struct_init.has_update_expr && !c.pref.translated { | ||||
| 				if field.typ.is_ptr() && !field.typ.has_flag(.shared_f) | ||||
| 					&& !struct_init.has_update_expr && !c.pref.translated { | ||||
| 					c.error('reference field `${type_sym.name}.$field.name` must be initialized', | ||||
| 						struct_init.pos) | ||||
| 				} | ||||
|  |  | |||
|  | @ -5743,23 +5743,36 @@ fn (mut g Gen) type_default(typ_ ast.Type) string { | |||
| 		return '{0}' | ||||
| 	} | ||||
| 	// Always set pointers to 0
 | ||||
| 	if typ.is_ptr() { | ||||
| 	if typ.is_ptr() && !typ.has_flag(.shared_f) { | ||||
| 		return '0' | ||||
| 	} | ||||
| 	sym := g.table.get_type_symbol(typ) | ||||
| 	if sym.kind == .array { | ||||
| 		elem_sym := g.typ(sym.array_info().elem_type) | ||||
| 		elem_typ := sym.array_info().elem_type | ||||
| 		elem_sym := g.typ(elem_typ) | ||||
| 		mut elem_type_str := util.no_dots(elem_sym) | ||||
| 		if elem_type_str.starts_with('C__') { | ||||
| 			elem_type_str = elem_type_str[3..] | ||||
| 		} | ||||
| 		return '__new_array(0, 1, sizeof($elem_type_str))' | ||||
| 		init_str := '__new_array(0, 1, sizeof($elem_type_str))' | ||||
| 		if typ.has_flag(.shared_f) { | ||||
| 			atyp := '__shared__Array_${g.table.get_type_symbol(elem_typ).cname}' | ||||
| 			return '($atyp*)__dup_shared_array(&($atyp){.val = $init_str}, sizeof($atyp))' | ||||
| 		} else { | ||||
| 			return init_str | ||||
| 		} | ||||
| 	} | ||||
| 	if sym.kind == .map { | ||||
| 		info := sym.map_info() | ||||
| 		key_typ := g.table.get_type_symbol(info.key_type) | ||||
| 		hash_fn, key_eq_fn, clone_fn, free_fn := g.map_fn_ptrs(key_typ) | ||||
| 		return 'new_map(sizeof(${g.typ(info.key_type)}), sizeof(${g.typ(info.value_type)}), $hash_fn, $key_eq_fn, $clone_fn, $free_fn)' | ||||
| 		init_str := 'new_map(sizeof(${g.typ(info.key_type)}), sizeof(${g.typ(info.value_type)}), $hash_fn, $key_eq_fn, $clone_fn, $free_fn)' | ||||
| 		if typ.has_flag(.shared_f) { | ||||
| 			mtyp := '__shared__Map_${key_typ.cname}_${g.table.get_type_symbol(info.value_type).cname}' | ||||
| 			return '($mtyp*)__dup_shared_map(&($mtyp){.val = $init_str}, sizeof($mtyp))' | ||||
| 		} else { | ||||
| 			return init_str | ||||
| 		} | ||||
| 	} | ||||
| 	// User struct defined in another module.
 | ||||
| 	// if typ.contains('__') {
 | ||||
|  | @ -5786,7 +5799,12 @@ fn (mut g Gen) type_default(typ_ ast.Type) string { | |||
| 		} else { | ||||
| 			init_str += '0}' | ||||
| 		} | ||||
| 		return init_str | ||||
| 		if typ.has_flag(.shared_f) { | ||||
| 			styp := '__shared__${g.table.get_type_symbol(typ).cname}' | ||||
| 			return '($styp*)__dup${styp}(&($styp){.val = $init_str}, sizeof($styp))' | ||||
| 		} else { | ||||
| 			return init_str | ||||
| 		} | ||||
| 	} | ||||
| 	// if typ.ends_with('Fn') { // TODO
 | ||||
| 	// return '0'
 | ||||
|  |  | |||
|  | @ -8,6 +8,18 @@ struct Abc { | |||
| 	i int | ||||
| } | ||||
| 
 | ||||
| fn test_shared_struct_auto_struct() { | ||||
| 	e := Abc{} | ||||
| 	shared a := e.a | ||||
| 	lock a { | ||||
| 		a.n = 17 | ||||
| 	} | ||||
| 	r := rlock a { | ||||
| 		a.n | ||||
| 	} | ||||
| 	assert r == 17 | ||||
| } | ||||
| 
 | ||||
| fn test_shared_struct_in_struct() { | ||||
| 	shared y := Xyz{ | ||||
| 		n: 7 | ||||
|  | @ -50,6 +62,20 @@ struct Efg { | |||
| 	i int | ||||
| } | ||||
| 
 | ||||
| fn test_shared_auto_init_array() { | ||||
| 	e := Efg{} | ||||
| 	shared a := e.a | ||||
| 	lock a { | ||||
| 		a << 23.0625 | ||||
| 		a << -133.25 | ||||
| 		a << 0.125 | ||||
| 	} | ||||
| 	r := rlock a { | ||||
| 		a[1] | ||||
| 	} | ||||
| 	assert r == -133.25 | ||||
| } | ||||
| 
 | ||||
| fn test_shared_array_in_struct() { | ||||
| 	x := Efg{ | ||||
| 		a: [1.25, 2.75, 7, 13.0625] | ||||
|  | @ -76,6 +102,18 @@ struct Hjk { | |||
| 	i int | ||||
| } | ||||
| 
 | ||||
| fn test_shared_auto_init_map() { | ||||
| 	a := Hjk{} | ||||
| 	shared m := a.m | ||||
| 	lock m { | ||||
| 		m['xcv'] = -31.125 | ||||
| 	} | ||||
| 	r := rlock m { | ||||
| 		m['xcv'] | ||||
| 	} | ||||
| 	assert r == -31.125 | ||||
| } | ||||
| 
 | ||||
| fn test_shared_map_in_struct() { | ||||
| 	x := Hjk{ | ||||
| 		m: map{ | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue