mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
checker, cgen: fix array of interfaces index() (#18232)
This commit is contained in:
parent
a33ffcedfb
commit
e2f18fc9cc
@ -4,6 +4,7 @@
|
||||
module checker
|
||||
|
||||
import v.ast
|
||||
import v.token
|
||||
|
||||
// TODO: promote(), check_types(), symmetric_check() and check() overlap - should be rearranged
|
||||
fn (mut c Checker) check_types(got ast.Type, expected ast.Type) bool {
|
||||
@ -274,6 +275,9 @@ fn (mut c Checker) check_expected_call_arg(got ast.Type, expected_ ast.Type, lan
|
||||
} else {
|
||||
got_typ_sym := c.table.sym(c.unwrap_generic(got))
|
||||
expected_typ_sym := c.table.sym(c.unwrap_generic(expected_))
|
||||
if expected_typ_sym.kind == .interface_ && c.type_implements(got, expected_, token.Pos{}) {
|
||||
return
|
||||
}
|
||||
|
||||
// Check on Generics types, there are some case where we have the following case
|
||||
// `&Type[int] == &Type[]`. This is a common case we are implementing a function
|
||||
|
@ -2519,6 +2519,9 @@ fn (mut c Checker) array_builtin_method_call(mut node ast.CallExpr, left_type as
|
||||
c.error('${err.msg()} in argument 1 to `.index()`', node.args[0].pos)
|
||||
}
|
||||
}
|
||||
for i, arg in node.args {
|
||||
node.args[i].typ = c.expr(arg.expr)
|
||||
}
|
||||
node.return_type = ast.int_type
|
||||
} else if method_name in ['first', 'last', 'pop'] {
|
||||
if node.args.len != 0 {
|
||||
|
@ -986,7 +986,12 @@ fn (mut g Gen) gen_array_index(node ast.CallExpr) {
|
||||
if node.args[0].expr.is_auto_deref_var() {
|
||||
g.write('*')
|
||||
}
|
||||
elem_typ := g.table.sym(node.left_type).array_info().elem_type
|
||||
if g.table.sym(elem_typ).kind in [.interface_, .sum_type] {
|
||||
g.expr_with_cast(node.args[0].expr, node.args[0].typ, elem_typ)
|
||||
} else {
|
||||
g.expr(node.args[0].expr)
|
||||
}
|
||||
g.write(')')
|
||||
}
|
||||
|
||||
|
31
vlib/v/tests/array_of_interfaces_index_test.v
Normal file
31
vlib/v/tests/array_of_interfaces_index_test.v
Normal file
@ -0,0 +1,31 @@
|
||||
struct Entity {
|
||||
id u64
|
||||
mut:
|
||||
components []IComponent
|
||||
}
|
||||
|
||||
interface IComponent {
|
||||
hollow bool
|
||||
}
|
||||
|
||||
struct IsControlledByPlayerTag {
|
||||
hollow bool
|
||||
}
|
||||
|
||||
fn get_component[T](entity Entity) !&T {
|
||||
for component in entity.components {
|
||||
if component is T {
|
||||
return component
|
||||
}
|
||||
}
|
||||
|
||||
return error('Entity does not have component')
|
||||
}
|
||||
|
||||
fn test_array_of_interfaces_index() {
|
||||
entity := Entity{1, [IsControlledByPlayerTag{}]}
|
||||
id := entity.components.index(*get_component[IsControlledByPlayerTag](entity)!)
|
||||
|
||||
println('id = ${id}')
|
||||
assert id == 0
|
||||
}
|
Loading…
Reference in New Issue
Block a user