cgen: fix typeof(expr).name for generic type, pointers, etc (#6712)
							parent
							
								
									2202ee5d66
								
							
						
					
					
						commit
						788de9938a
					
				| 
						 | 
				
			
			@ -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)}")')
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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'
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue