cgen: dereference in one place and fix
parent
3e6f7d3eb6
commit
af334e320c
|
@ -796,6 +796,20 @@ fn (mut g Gen) expr_with_cast(expr ast.Expr, got_type, expected_type table.Type)
|
|||
}
|
||||
}
|
||||
}
|
||||
// Generic dereferencing logic
|
||||
expected_sym := g.table.get_type_symbol(expected_type)
|
||||
got_is_ptr := got_type.is_ptr()
|
||||
expected_is_ptr := expected_type.is_ptr()
|
||||
neither_void := table.voidptr_type !in [got_type, expected_type]
|
||||
if got_is_ptr && !expected_is_ptr && neither_void && expected_sym.kind !in [.interface_, .placeholder] {
|
||||
got_deref_type := got_type.deref()
|
||||
deref_sym := g.table.get_type_symbol(got_deref_type)
|
||||
deref_will_match := expected_type in [got_type, got_deref_type, deref_sym.parent_idx]
|
||||
got_is_opt := got_type.flag_is(.optional)
|
||||
if deref_will_match || got_is_opt {
|
||||
g.write('*')
|
||||
}
|
||||
}
|
||||
// no cast
|
||||
g.expr(expr)
|
||||
}
|
||||
|
@ -2070,10 +2084,6 @@ fn (mut g Gen) return_statement(node ast.Return) {
|
|||
g.writeln(' }, sizeof($styp));')
|
||||
return
|
||||
}
|
||||
if !g.fn_decl.return_type.is_ptr() && node.types[0].is_ptr() {
|
||||
// Automatic Dereference
|
||||
g.write('*')
|
||||
}
|
||||
g.expr_with_cast(node.exprs[0], node.types[0], g.fn_decl.return_type)
|
||||
}
|
||||
g.writeln(';')
|
||||
|
|
|
@ -618,9 +618,6 @@ fn (mut g Gen) ref_or_deref_arg(arg ast.CallArg, expected_type table.Type) {
|
|||
if !g.is_json_fn {
|
||||
g.write('&/*qq*/')
|
||||
}
|
||||
} else if !arg_is_ptr && expr_is_ptr && exp_sym.kind != .interface_ {
|
||||
// Dereference a pointer if a value is required
|
||||
g.write('*/*d*/')
|
||||
}
|
||||
g.expr_with_cast(arg.expr, arg.typ, expected_type)
|
||||
}
|
||||
|
|
|
@ -51,3 +51,37 @@ fn test_assignment_and_push() {
|
|||
else {}
|
||||
}
|
||||
}
|
||||
|
||||
// Test moving structs between master/sub arrays
|
||||
|
||||
type Master = Sub1 | Sub2
|
||||
struct Sub1 {
|
||||
mut:
|
||||
val int
|
||||
name string
|
||||
}
|
||||
struct Sub2 {
|
||||
name string
|
||||
val int
|
||||
}
|
||||
|
||||
fn test_converting_down() {
|
||||
mut out := []Master{}
|
||||
out << Sub1 { val: 1, name: 'one' }
|
||||
out << Sub2 { val: 2, name: 'two'}
|
||||
out << Sub2 { val: 3, name: 'three'}
|
||||
|
||||
mut res := []Sub2{cap: out.len}
|
||||
for d in out {
|
||||
match d {
|
||||
Sub2 { res << it }
|
||||
else {}
|
||||
}
|
||||
}
|
||||
|
||||
assert res[0].val == 2
|
||||
assert res[0].name == 'two'
|
||||
assert res[1].val == 3
|
||||
assert res[1].name == 'three'
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue