Skip to content

Commit

Permalink
cgen, checker: fix wrong receiver generic resolution with embed types (
Browse files Browse the repository at this point in the history
  • Loading branch information
felipensp authored Jul 10, 2024
1 parent 547c056 commit 04ff511
Show file tree
Hide file tree
Showing 3 changed files with 120 additions and 3 deletions.
10 changes: 9 additions & 1 deletion vlib/v/checker/fn.v
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
13 changes: 11 additions & 2 deletions vlib/v/gen/c/fn.v
Original file line number Diff line number Diff line change
Expand Up @@ -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('->')
Expand Down
100 changes: 100 additions & 0 deletions vlib/v/tests/generic_receiver_embed_test.v
Original file line number Diff line number Diff line change
@@ -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
}

0 comments on commit 04ff511

Please sign in to comment.