Skip to content

Commit c01855c

Browse files
authored
cgen: fix $if typeof[T]().idx, $if typeof[T]().unaliased_typ checking (#23665)
1 parent 10f2fe1 commit c01855c

4 files changed

Lines changed: 69 additions & 12 deletions

File tree

‎vlib/v/gen/c/cgen.v‎

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3908,21 +3908,16 @@ fn (mut g Gen) selector_expr(node ast.SelectorExpr) {
39083908
}
39093909
g.type_name(name_type)
39103910
return
3911-
} else if node.field_name == 'idx' {
3911+
} else if node.field_name in ['idx', 'unaliased_typ'] {
3912+
// `typeof(expr).idx`, // `typeof(expr).unalised_typ`
39123913
mut name_type := node.name_type
39133914
if node.expr is ast.TypeOf {
3914-
name_type = g.type_resolver.typeof_type(node.expr.expr, name_type)
3915-
}
3916-
// `typeof(expr).idx`
3917-
g.write(int(g.unwrap_generic(name_type)).str())
3918-
return
3919-
} else if node.field_name == 'unaliased_typ' {
3920-
mut name_type := node.name_type
3921-
if node.expr is ast.TypeOf {
3922-
name_type = g.type_resolver.typeof_type(node.expr.expr, name_type)
3915+
name_type = g.type_resolver.typeof_field_type(g.type_resolver.typeof_type(node.expr.expr,
3916+
name_type), node.field_name)
3917+
g.write(int(name_type).str())
3918+
} else {
3919+
g.write(int(g.unwrap_generic(name_type)).str())
39233920
}
3924-
// `typeof(expr).unaliased_typ`
3925-
g.write(int(g.table.unaliased_type(g.unwrap_generic(name_type))).str())
39263921
return
39273922
} else if node.field_name == 'indirections' {
39283923
mut name_type := node.name_type

‎vlib/v/gen/c/comptime.v‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -455,6 +455,10 @@ fn (mut g Gen) get_expr_type(cond ast.Expr) ast.Type {
455455
} else if cond.gkind_field == .indirections {
456456
return ast.int_type
457457
} else {
458+
if cond.expr is ast.TypeOf {
459+
return g.type_resolver.typeof_field_type(g.type_resolver.typeof_type(cond.expr.expr,
460+
cond.name_type), cond.field_name)
461+
}
458462
name := '${cond.expr}.${cond.field_name}'
459463
if name in g.type_resolver.type_map {
460464
return g.type_resolver.get_ct_type_or_default(name, ast.void_type)
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
type MyInt = int
2+
type MyString = string
3+
4+
struct Foo {
5+
a []int
6+
b MyInt
7+
c MyString
8+
}
9+
10+
fn unaliased_typ[T](a T) int {
11+
$if typeof[T]().unaliased_typ is $int {
12+
return 1
13+
} $else $if typeof[T]().unaliased_typ is $string {
14+
return 2
15+
}
16+
return 0
17+
}
18+
19+
fn idx[T](a [][]T) int {
20+
$if typeof[T]().idx is $int {
21+
return 1
22+
} $else $if typeof[T]().idx is $string {
23+
return 2
24+
}
25+
return 0
26+
}
27+
28+
fn test_main() {
29+
a := Foo{
30+
a: [1, 2, 3]
31+
}
32+
assert idx([a.a]) == 1
33+
assert idx([['']]) == 2
34+
35+
assert unaliased_typ(1) == 1
36+
assert unaliased_typ('') == 2
37+
}

‎vlib/v/type_resolver/comptime_resolver.v‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,27 @@ pub fn (mut t TypeResolver) typeof_type(node ast.Expr, default_type ast.Type) as
8282
return default_type
8383
}
8484

85+
// typeof_field_type resolves the typeof[T]().<field_name> type
86+
pub fn (mut t TypeResolver) typeof_field_type(typ ast.Type, field_name string) ast.Type {
87+
match field_name {
88+
'name' {
89+
return ast.string_type
90+
}
91+
'idx' {
92+
return t.resolver.unwrap_generic(typ)
93+
}
94+
'unaliased_typ' {
95+
return t.table.unaliased_type(t.resolver.unwrap_generic(typ))
96+
}
97+
'indirections' {
98+
return ast.int_type
99+
}
100+
else {
101+
return typ
102+
}
103+
}
104+
}
105+
85106
// get_ct_type_var gets the comptime type of the variable (.generic_param, .key_var, etc)
86107
@[inline]
87108
pub fn (t &ResolverInfo) get_ct_type_var(node ast.Expr) ast.ComptimeVarKind {

0 commit comments

Comments
 (0)