Skip to content

Commit 04ff511

Browse files
authored
cgen, checker: fix wrong receiver generic resolution with embed types (#21833)
1 parent 547c056 commit 04ff511

File tree

3 files changed

+120
-3
lines changed

3 files changed

+120
-3
lines changed

vlib/v/checker/fn.v

+9-1
Original file line numberDiff line numberDiff line change
@@ -1589,15 +1589,23 @@ fn (mut c Checker) register_trace_call(node ast.CallExpr, func ast.Fn) {
15891589
fn (mut c Checker) is_generic_expr(node ast.Expr) bool {
15901590
return match node {
15911591
ast.Ident {
1592+
// variable declared as generic type
15921593
c.comptime.is_generic_param_var(node)
15931594
}
15941595
ast.IndexExpr {
1596+
// generic_var[N]
15951597
c.comptime.is_generic_param_var(node.left)
15961598
}
15971599
ast.CallExpr {
1598-
node.args.any(c.comptime.is_generic_param_var(it.expr))
1600+
// fn which has any generic dependent expr
1601+
if node.args.any(c.comptime.is_generic_param_var(it.expr)) {
1602+
return true
1603+
}
1604+
// fn[T]() or generic_var.fn[T]()
1605+
node.concrete_types.any(it.has_flag(.generic))
15991606
}
16001607
ast.SelectorExpr {
1608+
// generic_var.property
16011609
c.comptime.is_generic_param_var(node.expr)
16021610
}
16031611
else {

vlib/v/gen/c/fn.v

+11-2
Original file line numberDiff line numberDiff line change
@@ -1804,13 +1804,22 @@ fn (mut g Gen) method_call(node ast.CallExpr) {
18041804
g.expr(node.left)
18051805
}
18061806
if !is_interface || node.from_embed_types.len == 0 {
1807-
for i, embed in node.from_embed_types {
1807+
mut node_embed_types := node.from_embed_types.clone()
1808+
if node.left is ast.Ident && g.comptime.get_ct_type_var(node.left) == .generic_var {
1809+
_, embed_types := g.table.find_method_from_embeds(final_left_sym, node.name) or {
1810+
ast.Fn{}, []ast.Type{}
1811+
}
1812+
if embed_types.len > 0 {
1813+
node_embed_types = embed_types.clone()
1814+
}
1815+
}
1816+
for i, embed in node_embed_types {
18081817
embed_sym := g.table.sym(embed)
18091818
embed_name := embed_sym.embed_name()
18101819
is_left_ptr := if i == 0 {
18111820
left_type.is_ptr()
18121821
} else {
1813-
node.from_embed_types[i - 1].is_ptr()
1822+
node_embed_types[i - 1].is_ptr()
18141823
}
18151824
if is_left_ptr {
18161825
g.write('->')
+100
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
pub type Entity = u64
2+
type ComponentType = u16
3+
4+
pub struct Context {
5+
pub mut:
6+
ecs &Ecs
7+
}
8+
9+
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
10+
pub struct EntityManager {
11+
mut:
12+
living_entity_count u64
13+
}
14+
15+
fn (mut self EntityManager) create_entity() Entity {
16+
entity := self.living_entity_count
17+
self.living_entity_count++
18+
return entity
19+
}
20+
21+
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
22+
23+
pub interface ISystem {
24+
ecs &Ecs
25+
mut:
26+
init()
27+
}
28+
29+
pub struct System {
30+
pub mut:
31+
ecs &Ecs
32+
}
33+
34+
pub fn (mut self System) init() {
35+
}
36+
37+
pub struct SystemManager {
38+
mut:
39+
system_array map[string]ISystem = {}
40+
}
41+
42+
fn (mut self SystemManager) add_system[T]() &T {
43+
mut t := T{}
44+
self.system_array[typeof[T]().name] = t
45+
return &t
46+
}
47+
48+
////////////////////////////////////////////////////////////////////////////
49+
50+
@[heap]
51+
pub struct Ecs {
52+
mut:
53+
entity_manager EntityManager
54+
system_manager SystemManager
55+
pub mut:
56+
root_entity Entity
57+
}
58+
59+
pub fn Ecs.new() &Ecs {
60+
mut ecs := &Ecs{}
61+
ecs.root_entity = ecs.create_entity()
62+
return ecs
63+
}
64+
65+
pub fn (mut self Ecs) create_entity() Entity {
66+
return self.entity_manager.create_entity()
67+
}
68+
69+
pub fn (mut self Ecs) add_system[T]() {
70+
mut system := self.system_manager.add_system[T]()
71+
system.ecs = &self
72+
system.init()
73+
}
74+
75+
////////////////////////////////////////////////////////////////////////////////////////////////////////
76+
77+
struct NetworkUdpServerComponent {
78+
}
79+
80+
struct NetworkServerSystemUdp {
81+
System
82+
}
83+
84+
pub struct ConfigSystem {
85+
System
86+
}
87+
88+
struct NetworkServerSystemUdpExt {
89+
NetworkServerSystemUdp
90+
}
91+
92+
fn test_main() {
93+
mut ecs := Ecs.new()
94+
mut root_entity := ecs.create_entity()
95+
96+
ecs.add_system[ConfigSystem]()
97+
ecs.add_system[NetworkServerSystemUdpExt]()
98+
99+
assert true
100+
}

0 commit comments

Comments
 (0)