1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

cgen, checker: fix indexexpr with sumtype of array types (#18515)

This commit is contained in:
Felipe Pena 2023-06-24 03:09:49 -03:00 committed by GitHub
parent 4c9c515f8b
commit 2abd2e2c2a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 63 additions and 6 deletions

View File

@ -4035,8 +4035,8 @@ fn (mut c Checker) type_error_for_operator(op_label string, types_label string,
}
fn (mut c Checker) check_index(typ_sym &ast.TypeSymbol, index ast.Expr, index_type ast.Type, pos token.Pos, range_index bool, is_gated bool) {
index_type_sym := c.table.sym(index_type)
if typ_sym.kind in [.array, .array_fixed, .string] {
index_type_sym := c.table.sym(index_type)
if !(index_type.is_int() || index_type_sym.kind == .enum_
|| (index_type_sym.kind == .alias
&& (index_type_sym.info as ast.Alias).parent_type.is_int())
@ -4102,10 +4102,17 @@ fn (mut c Checker) index_expr(mut node ast.IndexExpr) ast.Type {
}
else {}
}
is_aggregate_arr := typ_sym.kind == .aggregate
&& (typ_sym.info as ast.Aggregate).types.filter(c.table.type_kind(it) !in [.array, .array_fixed, .string, .map]).len == 0
if typ_sym.kind !in [.array, .array_fixed, .string, .map] && !typ.is_ptr()
&& typ !in [ast.byteptr_type, ast.charptr_type] && !typ.has_flag(.variadic) {
&& typ !in [ast.byteptr_type, ast.charptr_type] && !typ.has_flag(.variadic)
&& !is_aggregate_arr {
c.error('type `${typ_sym.name}` does not support indexing', node.pos)
}
if is_aggregate_arr {
// treating indexexpr of sumtype of array types
typ = (typ_sym.info as ast.Aggregate).types[0]
}
if typ.has_flag(.option) {
if node.left is ast.Ident && (node.left as ast.Ident).or_expr.kind == .absent {
c.error('type `?${typ_sym.name}` is an Option, it must be unwrapped first; use `var?[]` to do it',

View File

@ -49,10 +49,17 @@ fn (mut g Gen) index_expr(node ast.IndexExpr) {
}
}
} else {
g.expr(node.left)
g.write('[')
g.expr(node.index)
g.write(']')
if sym.kind == .aggregate
&& (sym.info as ast.Aggregate).types.filter(g.table.type_kind(it) !in [.array, .array_fixed, .string, .map]).len == 0 {
// treating sumtype of array types
unwrapped_got_type := (sym.info as ast.Aggregate).types[g.aggregate_type_idx]
g.index_expr(ast.IndexExpr{ ...node, left_type: unwrapped_got_type })
} else {
g.expr(node.left)
g.write('[')
g.expr(node.index)
g.write(']')
}
}
}
}

View File

@ -0,0 +1,43 @@
type MySumType = []MyStructA | []MyStructB
type MySumTypePtr = []&MyStructA | []&MyStructB
struct ParentStruct {
parent_field string
}
struct MyStructA {
ParentStruct
}
struct MyStructB {
ParentStruct
}
fn check(mut t MySumType) {
match mut t {
[]MyStructA, []MyStructB {
println(t[0].parent_field)
}
}
}
fn check2(mut t MySumTypePtr) {
match mut t {
[]&MyStructA, []&MyStructB {
println(t[0].parent_field)
}
}
}
fn test_main() {
s := MyStructA{
parent_field: 'common'
}
mut t := MySumType([s])
mut t2 := MySumTypePtr([&s])
check(mut t)
check2(mut t2)
assert true
}