cgen: fix typeof union sum type (#6794)
parent
24f743ee12
commit
9c569246ef
|
@ -381,6 +381,22 @@ pub fn (mut g Gen) write_typeof_functions() {
|
|||
g.writeln('}')
|
||||
}
|
||||
}
|
||||
for typ in g.table.types {
|
||||
if typ.kind == .union_sum_type {
|
||||
sum_info := typ.info as table.UnionSumType
|
||||
tidx := g.table.find_type_idx(typ.name)
|
||||
g.writeln('char * v_typeof_unionsumtype_${tidx}(int sidx) { /* $typ.name */ ')
|
||||
g.writeln(' switch(sidx) {')
|
||||
g.writeln(' case $tidx: return "${util.strip_main_name(typ.name)}";')
|
||||
for v in sum_info.variants {
|
||||
subtype := g.table.get_type_symbol(v)
|
||||
g.writeln(' case $v: return "${util.strip_main_name(subtype.name)}";')
|
||||
}
|
||||
g.writeln(' default: return "unknown ${util.strip_main_name(typ.name)}";')
|
||||
g.writeln(' }')
|
||||
g.writeln('}')
|
||||
}
|
||||
}
|
||||
g.writeln('// << typeof() support for sum types')
|
||||
g.writeln('')
|
||||
}
|
||||
|
@ -2566,6 +2582,13 @@ fn (mut g Gen) typeof_expr(node ast.TypeOf) {
|
|||
g.write('tos3( /* $sym.name */ v_typeof_sumtype_${sum_type_idx}( (')
|
||||
g.expr(node.expr)
|
||||
g.write(').typ ))')
|
||||
} else if sym.kind == .union_sum_type {
|
||||
// When encountering a .sum_type, typeof() should be done at runtime,
|
||||
// because the subtype of the expression may change:
|
||||
sum_type_idx := node.expr_type.idx()
|
||||
g.write('tos3( /* $sym.name */ v_typeof_unionsumtype_${sum_type_idx}( (')
|
||||
g.expr(node.expr)
|
||||
g.write(').typ ))')
|
||||
} else if sym.kind == .array_fixed {
|
||||
fixed_info := sym.info as table.ArrayFixed
|
||||
typ_name := g.table.get_type_name(fixed_info.elem_type)
|
||||
|
|
|
@ -24,7 +24,7 @@ fn handle(e Expr) string {
|
|||
assert is_literal
|
||||
assert !(e !is IntegerLiteral)
|
||||
if e is IntegerLiteral {
|
||||
println('int')
|
||||
assert typeof(e.val) == 'string'
|
||||
}
|
||||
match union e {
|
||||
IntegerLiteral {
|
||||
|
@ -294,7 +294,7 @@ fn test_nested_if_is() {
|
|||
mut b := Outer(InnerStruct{Inner(0)})
|
||||
if b is InnerStruct {
|
||||
if b.x is int {
|
||||
println(b.x)
|
||||
assert b.x == 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -303,20 +303,30 @@ fn test_casted_sum_type_selector_reassign() {
|
|||
mut b := InnerStruct{Inner(0)}
|
||||
if b.x is int {
|
||||
assert typeof(b.x) == 'int'
|
||||
// this check works only if x is castet
|
||||
assert b.x == 0
|
||||
b.x = 'test'
|
||||
// this check works only if x is castet
|
||||
assert b.x[0] == `t`
|
||||
assert typeof(b.x) == 'string'
|
||||
}
|
||||
assert typeof(b.x) == 'Inner'
|
||||
// this check works only if x is not castet
|
||||
assert b.x is string
|
||||
}
|
||||
|
||||
fn test_casted_sum_type_ident_reassign() {
|
||||
mut x := Inner(0)
|
||||
if x is int {
|
||||
// this check works only if x is castet
|
||||
assert x == 0
|
||||
assert typeof(x) == 'int'
|
||||
x = 'test'
|
||||
// this check works only if x is castet
|
||||
assert x[0] == `t`
|
||||
assert typeof(x) == 'string'
|
||||
}
|
||||
assert typeof(x) == 'Inner'
|
||||
// this check works only if x is not castet
|
||||
assert x is string
|
||||
}
|
||||
|
||||
__type Expr2 = int | string
|
||||
|
@ -427,11 +437,17 @@ fn test_match_multi_branch() {
|
|||
mut y := ''
|
||||
match union f {
|
||||
CallExpr2, CTempVarExpr {
|
||||
assert typeof(f) == 'Expr4'
|
||||
// this check works only if f is not castet
|
||||
assert f is CTempVarExpr
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn test_typeof() {
|
||||
x := Expr4(CTempVarExpr{})
|
||||
assert typeof(x) == 'CTempVarExpr'
|
||||
}
|
||||
|
||||
struct Outer2 {
|
||||
e Expr4
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue