mirror of
https://github.com/vlang/v.git
synced 2025-09-10 07:47:20 -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 {
|
fn (mut c Checker) is_generic_expr(node ast.Expr) bool {
|
||||||
return match node {
|
return match node {
|
||||||
ast.Ident {
|
ast.Ident {
|
||||||
|
// variable declared as generic type
|
||||||
c.comptime.is_generic_param_var(node)
|
c.comptime.is_generic_param_var(node)
|
||||||
}
|
}
|
||||||
ast.IndexExpr {
|
ast.IndexExpr {
|
||||||
|
// generic_var[N]
|
||||||
c.comptime.is_generic_param_var(node.left)
|
c.comptime.is_generic_param_var(node.left)
|
||||||
}
|
}
|
||||||
ast.CallExpr {
|
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 {
|
ast.SelectorExpr {
|
||||||
|
// generic_var.property
|
||||||
c.comptime.is_generic_param_var(node.expr)
|
c.comptime.is_generic_param_var(node.expr)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -1804,13 +1804,22 @@ fn (mut g Gen) method_call(node ast.CallExpr) {
|
|||||||
g.expr(node.left)
|
g.expr(node.left)
|
||||||
}
|
}
|
||||||
if !is_interface || node.from_embed_types.len == 0 {
|
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_sym := g.table.sym(embed)
|
||||||
embed_name := embed_sym.embed_name()
|
embed_name := embed_sym.embed_name()
|
||||||
is_left_ptr := if i == 0 {
|
is_left_ptr := if i == 0 {
|
||||||
left_type.is_ptr()
|
left_type.is_ptr()
|
||||||
} else {
|
} else {
|
||||||
node.from_embed_types[i - 1].is_ptr()
|
node_embed_types[i - 1].is_ptr()
|
||||||
}
|
}
|
||||||
if is_left_ptr {
|
if is_left_ptr {
|
||||||
g.write('->')
|
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