cgen: dereference in one place and fix

pull/4874/head
Tanel Liiv 2020-05-13 02:01:34 +03:00 committed by GitHub
parent 3e6f7d3eb6
commit af334e320c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 48 additions and 7 deletions

View File

@ -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(';')

View File

@ -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)
}

View File

@ -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'
}