mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
cgen: fix typeof union sum type (#6794)
This commit is contained in:
parent
24f743ee12
commit
9c569246ef
@ -381,6 +381,22 @@ pub fn (mut g Gen) write_typeof_functions() {
|
|||||||
g.writeln('}')
|
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('// << typeof() support for sum types')
|
||||||
g.writeln('')
|
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.write('tos3( /* $sym.name */ v_typeof_sumtype_${sum_type_idx}( (')
|
||||||
g.expr(node.expr)
|
g.expr(node.expr)
|
||||||
g.write(').typ ))')
|
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 {
|
} else if sym.kind == .array_fixed {
|
||||||
fixed_info := sym.info as table.ArrayFixed
|
fixed_info := sym.info as table.ArrayFixed
|
||||||
typ_name := g.table.get_type_name(fixed_info.elem_type)
|
typ_name := g.table.get_type_name(fixed_info.elem_type)
|
||||||
|
@ -24,7 +24,7 @@ fn handle(e Expr) string {
|
|||||||
assert is_literal
|
assert is_literal
|
||||||
assert !(e !is IntegerLiteral)
|
assert !(e !is IntegerLiteral)
|
||||||
if e is IntegerLiteral {
|
if e is IntegerLiteral {
|
||||||
println('int')
|
assert typeof(e.val) == 'string'
|
||||||
}
|
}
|
||||||
match union e {
|
match union e {
|
||||||
IntegerLiteral {
|
IntegerLiteral {
|
||||||
@ -294,7 +294,7 @@ fn test_nested_if_is() {
|
|||||||
mut b := Outer(InnerStruct{Inner(0)})
|
mut b := Outer(InnerStruct{Inner(0)})
|
||||||
if b is InnerStruct {
|
if b is InnerStruct {
|
||||||
if b.x is int {
|
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)}
|
mut b := InnerStruct{Inner(0)}
|
||||||
if b.x is int {
|
if b.x is int {
|
||||||
assert typeof(b.x) == 'int'
|
assert typeof(b.x) == 'int'
|
||||||
|
// this check works only if x is castet
|
||||||
|
assert b.x == 0
|
||||||
b.x = 'test'
|
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) == '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() {
|
fn test_casted_sum_type_ident_reassign() {
|
||||||
mut x := Inner(0)
|
mut x := Inner(0)
|
||||||
if x is int {
|
if x is int {
|
||||||
|
// this check works only if x is castet
|
||||||
|
assert x == 0
|
||||||
assert typeof(x) == 'int'
|
assert typeof(x) == 'int'
|
||||||
x = 'test'
|
x = 'test'
|
||||||
|
// this check works only if x is castet
|
||||||
|
assert x[0] == `t`
|
||||||
assert typeof(x) == 'string'
|
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
|
__type Expr2 = int | string
|
||||||
@ -427,11 +437,17 @@ fn test_match_multi_branch() {
|
|||||||
mut y := ''
|
mut y := ''
|
||||||
match union f {
|
match union f {
|
||||||
CallExpr2, CTempVarExpr {
|
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 {
|
struct Outer2 {
|
||||||
e Expr4
|
e Expr4
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user