cgen: fix typeof(expr).name for generic type, pointers, etc (#6712)

pull/6719/head
Nick Treleaven 2020-11-02 21:59:48 +00:00 committed by GitHub
parent 2202ee5d66
commit 788de9938a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 46 additions and 11 deletions

View File

@ -2386,17 +2386,19 @@ fn (mut g Gen) expr(node ast.Expr) {
// typeof(expr).name
fn (mut g Gen) typeof_name(node ast.TypeOf) {
sym := g.table.get_type_symbol(node.expr_type)
if sym.kind == .array {
info := sym.info as table.Array
mut s := g.table.get_type_name(info.elem_type)
s = util.strip_main_name(s)
g.write('tos_lit("[]$s")')
} else if sym.kind == .sum_type {
// new typeof() must be known at compile-time
g.write('tos_lit("${util.strip_main_name(sym.name)}")')
} else {
mut typ := node.expr_type
if typ.has_flag(.generic) {
typ = g.cur_generic_type
}
sym := g.table.get_type_symbol(typ)
// TODO: fix table.type_to_str and use instead
if sym.kind == .function {
g.typeof_expr(node)
} else {
// Note: typeof() must be known at compile-time
// sum types should not be handled dynamically
s := g.table.type_to_str(typ)
g.write('tos_lit("${util.strip_main_name(s)}")')
}
}

View File

@ -15,14 +15,24 @@ fn test_typeof_on_simple_expressions() {
// assert typeof(1.0 * 12.2) == 'any_float'
}
fn test_typeof_on_atypes() {
fn test_arrays() {
aint := []int{}
astring := []string{}
assert typeof(aint) == 'array_int'
assert typeof(astring) == 'array_string'
assert typeof(aint).name == '[]int'
assert typeof(astring).name == '[]string'
}
fn test_type_constructors() {
v := `c`
assert typeof(&v).name == '&rune'
assert typeof(&[v]).name == '&[]rune'
assert typeof([v]!!).name == '[1]rune'
assert typeof(&[v]!!).name == '&[1]rune'
assert typeof(&FooBar{}).name == '&FooBar'
}
struct FooBar {
x int
}
@ -55,6 +65,7 @@ fn test_typeof_on_sumtypes() {
assert typeof(a) == 'int'
assert typeof(b) == 'f32'
assert typeof(c) == 'FooBar'
// typeof should be known at compile-time for all types
assert typeof(a).name == 'MySumType'
assert typeof(b).name == 'MySumType'
assert typeof(c).name == 'MySumType'
@ -108,3 +119,25 @@ fn test_typeof_on_fn() {
assert typeof(myfn3).name == typeof(myfn3)
assert typeof(myfn4).name == typeof(myfn4)
}
fn type_name<T>(v T) string {
return typeof(v).name
}
fn array_item_type<T>(v []T) string {
return typeof(v[0]).name
}
fn test_generic_type() {
v := 5
assert type_name(v) == 'int'
//assert type_name(&v) == '&int'
//assert type_name([v]!!) == '[1]int'
assert type_name([v]) == '[]int'
assert type_name([[v]]) == '[][]int'
assert type_name(FooBar{}) == 'FooBar'
assert array_item_type([v]) == 'int'
assert array_item_type([[v]]) == '[]int'
//assert array_item_type([&v]) == '&int'
}