mirror of
https://github.com/vlang/v.git
synced 2025-08-03 17:57:59 -04:00
cgen: fix $if typeof[T]().idx
, $if typeof[T]().unaliased_typ
checking (#23665)
This commit is contained in:
parent
10f2fe196a
commit
c01855c588
@ -3908,21 +3908,16 @@ fn (mut g Gen) selector_expr(node ast.SelectorExpr) {
|
||||
}
|
||||
g.type_name(name_type)
|
||||
return
|
||||
} else if node.field_name == 'idx' {
|
||||
} else if node.field_name in ['idx', 'unaliased_typ'] {
|
||||
// `typeof(expr).idx`, // `typeof(expr).unalised_typ`
|
||||
mut name_type := node.name_type
|
||||
if node.expr is ast.TypeOf {
|
||||
name_type = g.type_resolver.typeof_type(node.expr.expr, name_type)
|
||||
name_type = g.type_resolver.typeof_field_type(g.type_resolver.typeof_type(node.expr.expr,
|
||||
name_type), node.field_name)
|
||||
g.write(int(name_type).str())
|
||||
} else {
|
||||
g.write(int(g.unwrap_generic(name_type)).str())
|
||||
}
|
||||
// `typeof(expr).idx`
|
||||
g.write(int(g.unwrap_generic(name_type)).str())
|
||||
return
|
||||
} else if node.field_name == 'unaliased_typ' {
|
||||
mut name_type := node.name_type
|
||||
if node.expr is ast.TypeOf {
|
||||
name_type = g.type_resolver.typeof_type(node.expr.expr, name_type)
|
||||
}
|
||||
// `typeof(expr).unaliased_typ`
|
||||
g.write(int(g.table.unaliased_type(g.unwrap_generic(name_type))).str())
|
||||
return
|
||||
} else if node.field_name == 'indirections' {
|
||||
mut name_type := node.name_type
|
||||
|
@ -455,6 +455,10 @@ fn (mut g Gen) get_expr_type(cond ast.Expr) ast.Type {
|
||||
} else if cond.gkind_field == .indirections {
|
||||
return ast.int_type
|
||||
} else {
|
||||
if cond.expr is ast.TypeOf {
|
||||
return g.type_resolver.typeof_field_type(g.type_resolver.typeof_type(cond.expr.expr,
|
||||
cond.name_type), cond.field_name)
|
||||
}
|
||||
name := '${cond.expr}.${cond.field_name}'
|
||||
if name in g.type_resolver.type_map {
|
||||
return g.type_resolver.get_ct_type_or_default(name, ast.void_type)
|
||||
|
37
vlib/v/tests/generics/generic_typeof_idx_test.v
Normal file
37
vlib/v/tests/generics/generic_typeof_idx_test.v
Normal file
@ -0,0 +1,37 @@
|
||||
type MyInt = int
|
||||
type MyString = string
|
||||
|
||||
struct Foo {
|
||||
a []int
|
||||
b MyInt
|
||||
c MyString
|
||||
}
|
||||
|
||||
fn unaliased_typ[T](a T) int {
|
||||
$if typeof[T]().unaliased_typ is $int {
|
||||
return 1
|
||||
} $else $if typeof[T]().unaliased_typ is $string {
|
||||
return 2
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
fn idx[T](a [][]T) int {
|
||||
$if typeof[T]().idx is $int {
|
||||
return 1
|
||||
} $else $if typeof[T]().idx is $string {
|
||||
return 2
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
fn test_main() {
|
||||
a := Foo{
|
||||
a: [1, 2, 3]
|
||||
}
|
||||
assert idx([a.a]) == 1
|
||||
assert idx([['']]) == 2
|
||||
|
||||
assert unaliased_typ(1) == 1
|
||||
assert unaliased_typ('') == 2
|
||||
}
|
@ -82,6 +82,27 @@ pub fn (mut t TypeResolver) typeof_type(node ast.Expr, default_type ast.Type) as
|
||||
return default_type
|
||||
}
|
||||
|
||||
// typeof_field_type resolves the typeof[T]().<field_name> type
|
||||
pub fn (mut t TypeResolver) typeof_field_type(typ ast.Type, field_name string) ast.Type {
|
||||
match field_name {
|
||||
'name' {
|
||||
return ast.string_type
|
||||
}
|
||||
'idx' {
|
||||
return t.resolver.unwrap_generic(typ)
|
||||
}
|
||||
'unaliased_typ' {
|
||||
return t.table.unaliased_type(t.resolver.unwrap_generic(typ))
|
||||
}
|
||||
'indirections' {
|
||||
return ast.int_type
|
||||
}
|
||||
else {
|
||||
return typ
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// get_ct_type_var gets the comptime type of the variable (.generic_param, .key_var, etc)
|
||||
@[inline]
|
||||
pub fn (t &ResolverInfo) get_ct_type_var(node ast.Expr) ast.ComptimeVarKind {
|
||||
|
Loading…
x
Reference in New Issue
Block a user