mirror of
https://github.com/vlang/v.git
synced 2025-09-08 06:41:58 -04:00
cgen, checker: fix wrong receiver generic resolution with embed types (#21833)
This commit is contained in:
parent
547c056bf4
commit
04ff511e27
@ -1589,15 +1589,23 @@ fn (mut c Checker) register_trace_call(node ast.CallExpr, func ast.Fn) {
|
||||
fn (mut c Checker) is_generic_expr(node ast.Expr) bool {
|
||||
return match node {
|
||||
ast.Ident {
|
||||
// variable declared as generic type
|
||||
c.comptime.is_generic_param_var(node)
|
||||
}
|
||||
ast.IndexExpr {
|
||||
// generic_var[N]
|
||||
c.comptime.is_generic_param_var(node.left)
|
||||
}
|
||||
ast.CallExpr {
|
||||
node.args.any(c.comptime.is_generic_param_var(it.expr))
|
||||
// fn which has any generic dependent expr
|
||||
if node.args.any(c.comptime.is_generic_param_var(it.expr)) {
|
||||
return true
|
||||
}
|
||||
// fn[T]() or generic_var.fn[T]()
|
||||
node.concrete_types.any(it.has_flag(.generic))
|
||||
}
|
||||
ast.SelectorExpr {
|
||||
// generic_var.property
|
||||
c.comptime.is_generic_param_var(node.expr)
|
||||
}
|
||||
else {
|
||||
|
@ -1804,13 +1804,22 @@ fn (mut g Gen) method_call(node ast.CallExpr) {
|
||||
g.expr(node.left)
|
||||
}
|
||||
if !is_interface || node.from_embed_types.len == 0 {
|
||||
for i, embed in node.from_embed_types {
|
||||
mut node_embed_types := node.from_embed_types.clone()
|
||||
if node.left is ast.Ident && g.comptime.get_ct_type_var(node.left) == .generic_var {
|
||||
_, embed_types := g.table.find_method_from_embeds(final_left_sym, node.name) or {
|
||||
ast.Fn{}, []ast.Type{}
|
||||
}
|
||||
if embed_types.len > 0 {
|
||||
node_embed_types = embed_types.clone()
|
||||
}
|
||||
}
|
||||
for i, embed in node_embed_types {
|
||||
embed_sym := g.table.sym(embed)
|
||||
embed_name := embed_sym.embed_name()
|
||||
is_left_ptr := if i == 0 {
|
||||
left_type.is_ptr()
|
||||
} else {
|
||||
node.from_embed_types[i - 1].is_ptr()
|
||||
node_embed_types[i - 1].is_ptr()
|
||||
}
|
||||
if is_left_ptr {
|
||||
g.write('->')
|
||||
|
100
vlib/v/tests/generic_receiver_embed_test.v
Normal file
100
vlib/v/tests/generic_receiver_embed_test.v
Normal file
@ -0,0 +1,100 @@
|
||||
pub type Entity = u64
|
||||
type ComponentType = u16
|
||||
|
||||
pub struct Context {
|
||||
pub mut:
|
||||
ecs &Ecs
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
pub struct EntityManager {
|
||||
mut:
|
||||
living_entity_count u64
|
||||
}
|
||||
|
||||
fn (mut self EntityManager) create_entity() Entity {
|
||||
entity := self.living_entity_count
|
||||
self.living_entity_count++
|
||||
return entity
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
pub interface ISystem {
|
||||
ecs &Ecs
|
||||
mut:
|
||||
init()
|
||||
}
|
||||
|
||||
pub struct System {
|
||||
pub mut:
|
||||
ecs &Ecs
|
||||
}
|
||||
|
||||
pub fn (mut self System) init() {
|
||||
}
|
||||
|
||||
pub struct SystemManager {
|
||||
mut:
|
||||
system_array map[string]ISystem = {}
|
||||
}
|
||||
|
||||
fn (mut self SystemManager) add_system[T]() &T {
|
||||
mut t := T{}
|
||||
self.system_array[typeof[T]().name] = t
|
||||
return &t
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@[heap]
|
||||
pub struct Ecs {
|
||||
mut:
|
||||
entity_manager EntityManager
|
||||
system_manager SystemManager
|
||||
pub mut:
|
||||
root_entity Entity
|
||||
}
|
||||
|
||||
pub fn Ecs.new() &Ecs {
|
||||
mut ecs := &Ecs{}
|
||||
ecs.root_entity = ecs.create_entity()
|
||||
return ecs
|
||||
}
|
||||
|
||||
pub fn (mut self Ecs) create_entity() Entity {
|
||||
return self.entity_manager.create_entity()
|
||||
}
|
||||
|
||||
pub fn (mut self Ecs) add_system[T]() {
|
||||
mut system := self.system_manager.add_system[T]()
|
||||
system.ecs = &self
|
||||
system.init()
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct NetworkUdpServerComponent {
|
||||
}
|
||||
|
||||
struct NetworkServerSystemUdp {
|
||||
System
|
||||
}
|
||||
|
||||
pub struct ConfigSystem {
|
||||
System
|
||||
}
|
||||
|
||||
struct NetworkServerSystemUdpExt {
|
||||
NetworkServerSystemUdp
|
||||
}
|
||||
|
||||
fn test_main() {
|
||||
mut ecs := Ecs.new()
|
||||
mut root_entity := ecs.create_entity()
|
||||
|
||||
ecs.add_system[ConfigSystem]()
|
||||
ecs.add_system[NetworkServerSystemUdpExt]()
|
||||
|
||||
assert true
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user