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
|
||||
}
|
||||
right_first := node.right[0]
|
||||
node.left_types = []
|
||||
mut right_len := node.right.len
|
||||
mut right_type0 := ast.void_type
|
||||
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] }
|
||||
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 {
|
||||
// check generic struct init and return unwrap generic struct type
|
||||
if right is ast.StructInit {
|
||||
|
@ -3484,6 +3495,10 @@ pub fn (mut c Checker) assign_stmt(mut node ast.AssignStmt) {
|
|||
c.expr(right)
|
||||
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() {
|
||||
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 {
|
||||
g.out.write_string(util.tabs(g.indent - g.inside_ternary))
|
||||
}
|
||||
mut is_used_var_styp := false
|
||||
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 {
|
||||
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