@@ -382,6 +382,34 @@ fn (mut g Generics) cc_type(typ ast.Type, is_prefix_struct bool) string {
382382 return styp
383383}
384384
385+ pub fn (mut g Generics) method_concrete_name (old_name string , concrete_types []ast.Type, receiver_type ast.Type) string {
386+ mut name := old_name
387+ if receiver_type != 0 {
388+ info := g.table.sym (g.unwrap_generic (receiver_type)).info
389+ if info is ast.Struct {
390+ fn_conc_types := concrete_types[info.generic_types.len..] // concrete types without the generic types of the struct
391+
392+ if fn_conc_types.len > 0 {
393+ name + = '_T'
394+ }
395+ for typ in fn_conc_types {
396+ name + = '_' + strings.repeat_string ('__ptr__' , typ.nr_muls ()) +
397+ g.styp (typ.set_nr_muls (0 ))
398+ }
399+ return name
400+ } else if info is ast.Interface {
401+ return name
402+ }
403+ }
404+ if concrete_types.len > 0 {
405+ name + = '_T'
406+ }
407+ for typ in concrete_types {
408+ name + = '_' + strings.repeat_string ('__ptr__' , typ.nr_muls ()) + g.styp (typ.set_nr_muls (0 ))
409+ }
410+ return name
411+ }
412+
385413pub fn (mut g Generics) concrete_name (old_name string , concrete_types []ast.Type) string {
386414 mut name := old_name
387415 if concrete_types.len > 0 {
@@ -409,12 +437,50 @@ pub fn (mut g Generics) generic_fn_decl(mut node ast.FnDecl) []ast.Stmt {
409437 ...node
410438 }
411439 new_node = g.stmt (mut new_node) as ast.FnDecl
412- solved_fns << ast.FnDecl{
440+ new_node = ast.FnDecl{
413441 ...new_node
414- name: g.concrete_name (new_node.name, concrete_types)
442+ name: if node.is_method {
443+ g.method_concrete_name (new_node.name, concrete_types, new_node.receiver.typ)
444+ } else {
445+ g.concrete_name (new_node.name, concrete_types)
446+ }
415447 ninstances: 0
416448 generic_names: []
417449 }
450+ if new_node.is_method {
451+ mut sym := g.table.sym (new_node.receiver.typ)
452+ func := ast.Fn{
453+ is_variadic: new_node.is_variadic
454+ is_c_variadic: new_node.is_c_variadic
455+ language: .v
456+ is_pub: new_node.is_pub
457+ is_deprecated: new_node.is_deprecated
458+ is_noreturn: new_node.is_noreturn
459+ is_unsafe: new_node.is_unsafe
460+ is_must_use: new_node.is_must_use
461+ is_keep_alive: new_node.is_keep_alive
462+ is_method: new_node.is_method
463+ is_static_type_method: new_node.is_static_type_method
464+ no_body: new_node.no_body
465+ is_file_translated: new_node.is_file_translated
466+ mod: new_node.mod
467+ file: new_node.file
468+ file_mode: new_node.file_mode
469+ pos: new_node.pos
470+ return_type_pos: new_node.return_type_pos
471+ return_type: new_node.return_type
472+ receiver_type: new_node.receiver.typ
473+ name: new_node.name
474+ params: new_node.params
475+ generic_names: []
476+ is_conditional: new_node.is_conditional
477+ ctdefine_idx: new_node.ctdefine_idx
478+ is_expand_simple_interpolation: new_node.is_expand_simple_interpolation
479+ }
480+ g.table.find_or_register_fn_type (func, false , true )
481+ sym.register_method (func)
482+ }
483+ solved_fns << new_node
418484 }
419485 g.cur_concrete_types = []
420486 return solved_fns
@@ -521,7 +587,11 @@ pub fn (mut g Generics) expr(mut node ast.Expr) ast.Expr {
521587 }
522588 return ast.Expr (ast.CallExpr{
523589 ...node
524- name: g.concrete_name (node.name, all_concrete_types)
590+ name: if node.is_method {
591+ g.method_concrete_name (node.name, all_concrete_types, node.receiver_type)
592+ } else {
593+ g.concrete_name (node.name, all_concrete_types)
594+ }
525595 left_type: g.unwrap_generic (node.left_type)
526596 receiver_type: g.unwrap_generic (node.receiver_type)
527597 return_type: g.unwrap_generic (node.return_type)
@@ -550,7 +620,11 @@ pub fn (mut g Generics) expr(mut node ast.Expr) ast.Expr {
550620 func.generic_names, node.concrete_types) or { it })
551621 }
552622 }
553- node.name = g.concrete_name (node.name, node.concrete_types)
623+ node.name = if node.is_method {
624+ g.method_concrete_name (node.name, node.concrete_types, node.receiver_type)
625+ } else {
626+ g.concrete_name (node.name, node.concrete_types)
627+ }
554628 return ast.Expr (ast.CallExpr{
555629 ...node
556630 concrete_types: []
@@ -700,6 +774,33 @@ pub fn (mut g Generics) expr(mut node ast.Expr) ast.Expr {
700774 })
701775 }
702776 }
777+ ast.EmptyScopeObject {
778+ if g.cur_concrete_types.len > 0 {
779+ mut typ := node.obj.typ
780+ mut name := node.name
781+ if typ == 0 {
782+ if g.cur_fn != unsafe { nil } {
783+ idx := g.cur_fn.generic_names.index (node.name)
784+ if idx != - 1 {
785+ typ = g.cur_concrete_types[idx]
786+ name = g.table.type_str (typ)
787+ }
788+ }
789+ } else {
790+ typ = g.unwrap_generic (typ)
791+ name = g.table.type_str (typ)
792+ }
793+ return ast.Expr (ast.Ident{
794+ ...node
795+ obj: ast.EmptyScopeObject{
796+ ...node.obj
797+ typ: typ
798+ name: name
799+ }
800+ name: name
801+ })
802+ }
803+ }
703804 else {}
704805 }
705806 }
@@ -917,7 +1018,6 @@ pub fn (mut g Generics) expr(mut node ast.Expr) ast.Expr {
9171018 typ: g.unwrap_generic (node.typ)
9181019 name_type: g.unwrap_generic (node.name_type)
9191020 from_embed_types: node.from_embed_types.map (g.unwrap_generic (it ))
920- gkind_field: .unknown
9211021 })
9221022 }
9231023 node.expr = g.expr (mut node.expr)
0 commit comments