parent
							
								
									eac8f77613
								
							
						
					
					
						commit
						fb9b2e873c
					
				|  | @ -3390,6 +3390,7 @@ pub fn (mut c Checker) assign_stmt(mut node ast.AssignStmt) { | ||||||
| 		c.expected_type = ast.void_type | 		c.expected_type = ast.void_type | ||||||
| 	} | 	} | ||||||
| 	right_first := node.right[0] | 	right_first := node.right[0] | ||||||
|  | 	node.left_types = [] | ||||||
| 	mut right_len := node.right.len | 	mut right_len := node.right.len | ||||||
| 	mut right_type0 := ast.void_type | 	mut right_type0 := ast.void_type | ||||||
| 	for i, right in node.right { | 	for i, right in node.right { | ||||||
|  | @ -3477,6 +3478,16 @@ pub fn (mut c Checker) assign_stmt(mut node ast.AssignStmt) { | ||||||
| 		} | 		} | ||||||
| 		right := if i < node.right.len { node.right[i] } else { node.right[0] } | 		right := if i < node.right.len { node.right[i] } else { node.right[0] } | ||||||
| 		mut right_type := node.right_types[i] | 		mut right_type := node.right_types[i] | ||||||
|  | 		if right is ast.Ident { | ||||||
|  | 			right_sym := c.table.get_type_symbol(right_type) | ||||||
|  | 			if right_sym.info is ast.Struct { | ||||||
|  | 				if right_sym.info.generic_types.len > 0 { | ||||||
|  | 					if obj := right.scope.find(right.name) { | ||||||
|  | 						right_type = obj.typ | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
| 		if is_decl { | 		if is_decl { | ||||||
| 			// check generic struct init and return unwrap generic struct type
 | 			// check generic struct init and return unwrap generic struct type
 | ||||||
| 			if right is ast.StructInit { | 			if right is ast.StructInit { | ||||||
|  | @ -3484,6 +3495,10 @@ pub fn (mut c Checker) assign_stmt(mut node ast.AssignStmt) { | ||||||
| 					c.expr(right) | 					c.expr(right) | ||||||
| 					right_type = right.typ | 					right_type = right.typ | ||||||
| 				} | 				} | ||||||
|  | 			} else if right is ast.PrefixExpr { | ||||||
|  | 				if right.op == .amp && right.right is ast.StructInit { | ||||||
|  | 					right_type = c.expr(right) | ||||||
|  | 				} | ||||||
| 			} | 			} | ||||||
| 			if right.is_auto_deref_var() { | 			if right.is_auto_deref_var() { | ||||||
| 				left_type = c.table.mktyp(right_type.deref()) | 				left_type = c.table.mktyp(right_type.deref()) | ||||||
|  |  | ||||||
|  | @ -2620,8 +2620,27 @@ fn (mut g Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) { | ||||||
| 					if is_inside_ternary { | 					if is_inside_ternary { | ||||||
| 						g.out.write_string(util.tabs(g.indent - g.inside_ternary)) | 						g.out.write_string(util.tabs(g.indent - g.inside_ternary)) | ||||||
| 					} | 					} | ||||||
|  | 					mut is_used_var_styp := false | ||||||
| 					if ident.name !in g.defer_vars { | 					if ident.name !in g.defer_vars { | ||||||
| 						g.write('$styp ') | 						val_sym := g.table.get_type_symbol(val_type) | ||||||
|  | 						if val_sym.info is ast.Struct { | ||||||
|  | 							if val_sym.info.generic_types.len > 0 { | ||||||
|  | 								if val is ast.StructInit { | ||||||
|  | 									var_styp := g.typ(val.typ) | ||||||
|  | 									g.write('$var_styp ') | ||||||
|  | 									is_used_var_styp = true | ||||||
|  | 								} else if val is ast.PrefixExpr { | ||||||
|  | 									if val.op == .amp && val.right is ast.StructInit { | ||||||
|  | 										var_styp := g.typ(val.right.typ.to_ptr()) | ||||||
|  | 										g.write('$var_styp ') | ||||||
|  | 										is_used_var_styp = true | ||||||
|  | 									} | ||||||
|  | 								} | ||||||
|  | 							} | ||||||
|  | 						} | ||||||
|  | 						if !is_used_var_styp { | ||||||
|  | 							g.write('$styp ') | ||||||
|  | 						} | ||||||
| 						if is_auto_heap { | 						if is_auto_heap { | ||||||
| 							g.write('*') | 							g.write('*') | ||||||
| 						} | 						} | ||||||
|  |  | ||||||
|  | @ -0,0 +1,46 @@ | ||||||
|  | pub struct List<T> { | ||||||
|  | pub mut: | ||||||
|  | 	head &ListNode<T> = 0 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | pub struct ListNode<T> { | ||||||
|  | pub mut: | ||||||
|  | 	value T | ||||||
|  | 	next  &ListNode<T> = 0 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | pub fn list_new<T>() List<T> { | ||||||
|  | 	return List<T>{} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | pub fn (mut l List<T>) add(value T) { | ||||||
|  | 	mut node := &ListNode<T>{value, 0} | ||||||
|  | 	if l.head == 0 { | ||||||
|  | 		l.head = node | ||||||
|  | 	} else { | ||||||
|  | 		node.next = l.head | ||||||
|  | 		l.head = node | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | fn test_generic_assign_reference_generic_struct() { | ||||||
|  | 	mut list1 := list_new<string>() | ||||||
|  | 	list1.add('hello') | ||||||
|  | 	println(list1.head.value) | ||||||
|  | 	assert list1.head.value == 'hello' | ||||||
|  | 
 | ||||||
|  | 	mut list2 := list_new<int>() | ||||||
|  | 	list2.add(100) | ||||||
|  | 	println(list2.head.value) | ||||||
|  | 	assert list2.head.value == 100 | ||||||
|  | 
 | ||||||
|  | 	mut list3 := list_new<f64>() | ||||||
|  | 	list3.add(22.2) | ||||||
|  | 	println(list3.head.value) | ||||||
|  | 	assert list3.head.value == 22.2 | ||||||
|  | 
 | ||||||
|  | 	mut list4 := list_new<bool>() | ||||||
|  | 	list4.add(true) | ||||||
|  | 	println(list4.head.value) | ||||||
|  | 	assert list4.head.value == true | ||||||
|  | } | ||||||
		Loading…
	
		Reference in New Issue