ast, parser, cgen: fix generic struct init (Stack[&Person]{}) (fix #19119) (#19122)

This commit is contained in:
yuyi 2023-08-12 16:43:20 +08:00 committed by GitHub
parent 3c26bfff55
commit 89bd575ec0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 34 additions and 1 deletions

View File

@ -1691,6 +1691,9 @@ pub fn (mut t Table) resolve_generic_to_concrete(generic_type Type, generic_name
t_generic_names, t_concrete_types)
{
gts := t.sym(ct)
if ct.is_ptr() {
nrt += '&'
}
nrt += gts.name
rnrt += gts.name
if i != sym.info.generic_types.len - 1 {
@ -1867,6 +1870,9 @@ pub fn (mut t Table) unwrap_generic_type(typ Type, generic_names []string, concr
t_concrete_types)
{
gts := t.sym(ct)
if ct.is_ptr() {
nrt += '&'
}
nrt += gts.name
c_nrt += gts.cname
if i != ts.info.generic_types.len - 1 {

View File

@ -184,20 +184,22 @@ fn (mut g Gen) if_expr(node ast.IfExpr) {
mut cur_line := ''
mut raw_state := false
if needs_tmp_var {
mut styp := g.typ(node.typ)
if node.typ.has_flag(.option) {
raw_state = g.inside_if_option
defer {
g.inside_if_option = raw_state
}
g.inside_if_option = true
styp = styp.replace('*', '_ptr')
} else if node.typ.has_flag(.result) {
raw_state = g.inside_if_result
defer {
g.inside_if_result = raw_state
}
g.inside_if_result = true
styp = styp.replace('*', '_ptr')
}
styp := g.typ(node.typ)
cur_line = g.go_before_stmt(0)
g.empty_line = true
g.writeln('${styp} ${tmp}; /* if prepend */')

View File

@ -763,6 +763,9 @@ fn (mut p Parser) parse_generic_inst_type(name string) ast.Type {
if gts.kind == .multi_return {
p.error_with_pos('cannot use multi return as generic concrete type', type_pos)
}
if gt.is_ptr() {
bs_name += '&'
}
bs_name += gts.name
bs_cname += gts.cname
concrete_types << gt

View File

@ -0,0 +1,22 @@
import datatypes { Stack }
struct Person {
mut:
name string
age int
}
fn test_generic_struct_init_with_reference_struct_type() {
mut adam := &Person{'Adam', 21}
println(adam)
mut people := Stack[&Person]{}
people.push(adam)
assert people.len() == 1
mut top_person := people.pop()!
top_person.age++
println(adam)
assert people.len() == 0
}