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
|
// no cast
|
||||||
g.expr(expr)
|
g.expr(expr)
|
||||||
}
|
}
|
||||||
|
@ -2070,10 +2084,6 @@ fn (mut g Gen) return_statement(node ast.Return) {
|
||||||
g.writeln(' }, sizeof($styp));')
|
g.writeln(' }, sizeof($styp));')
|
||||||
return
|
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.expr_with_cast(node.exprs[0], node.types[0], g.fn_decl.return_type)
|
||||||
}
|
}
|
||||||
g.writeln(';')
|
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 {
|
if !g.is_json_fn {
|
||||||
g.write('&/*qq*/')
|
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)
|
g.expr_with_cast(arg.expr, arg.typ, expected_type)
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,3 +51,37 @@ fn test_assignment_and_push() {
|
||||||
else {}
|
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