@@ -121,6 +121,28 @@ fn (g &Gen) method_decl_fkey(method ast.Fn) string {
121121 return method.fkey ()
122122}
123123
124+ fn (g &Gen) receiver_exact_method_for_type (typ ast.Type, method_name string ) ? ast.Fn {
125+ if typ == 0 {
126+ return none
127+ }
128+ sym := g.table.sym (typ)
129+ for method in sym.methods {
130+ if method.name == method_name && method.receiver_type == typ {
131+ return method
132+ }
133+ }
134+ if sym.info is ast.Alias {
135+ parent_type := sym.info.parent_type.derive (typ)
136+ parent_sym := g.table.sym (parent_type)
137+ for method in parent_sym.methods {
138+ if method.name == method_name && method.receiver_type == parent_type {
139+ return method
140+ }
141+ }
142+ }
143+ return none
144+ }
145+
124146fn (g &Gen) generic_parent_method_fkey (sym ast.TypeSymbol, method_name string ) string {
125147 match sym.info {
126148 ast.Struct, ast.Interface, ast.SumType {
@@ -242,6 +264,22 @@ fn (g &Gen) prefers_msvc_compatible_code() bool {
242264
243265fn (mut g Gen) node_decl_fkey (node ast.FnDecl) string {
244266 if node.is_method && ! node.name.contains ('_T_' ) {
267+ if ! node.receiver.typ.has_flag (.generic)
268+ && ! g.type_has_unresolved_generic_parts (node.receiver.typ) {
269+ if structured_method := g.table.find_structured_receiver_method_with_types (node.receiver.typ,
270+ node.name)
271+ {
272+ if structured_method.method.receiver_type != node.receiver.typ {
273+ if exact_method := g.receiver_exact_method_for_type (node.receiver.typ,
274+ node.name)
275+ {
276+ if g.method_decl_fkey (exact_method) == node.fkey () {
277+ return node.fkey ()
278+ }
279+ }
280+ }
281+ }
282+ }
245283 receiver_sym := g.table.sym (node.receiver.typ)
246284 receiver_has_concrete_generics := match receiver_sym.info {
247285 ast.Struct, ast.Interface, ast.SumType {
@@ -755,6 +793,20 @@ fn (mut g Gen) is_used_by_main(node ast.FnDecl) bool {
755793 }
756794 fkey := g.node_decl_fkey (node)
757795 is_used_by_main = g.table.used_features.used_fns[fkey]
796+ if ! is_used_by_main && node.is_method && ! node.receiver.typ.has_flag (.generic)
797+ && ! g.type_has_unresolved_generic_parts (node.receiver.typ) {
798+ if structured_method := g.table.find_structured_receiver_method_with_types (node.receiver.typ,
799+ node.name)
800+ {
801+ if structured_method.method.receiver_type != node.receiver.typ {
802+ if exact_method := g.receiver_exact_method_for_type (node.receiver.typ,
803+ node.name)
804+ {
805+ is_used_by_main = g.method_decl_fkey (exact_method) == node.fkey ()
806+ }
807+ }
808+ }
809+ }
758810 if ! is_used_by_main && g.effective_fn_generic_names (node).len > 0
759811 && g.table.fn_generic_types[fkey].len > 0 {
760812 is_used_by_main = true
@@ -3411,21 +3463,19 @@ fn (mut g Gen) resolve_receiver_name(node ast.CallExpr, unwrapped_rec_type ast.T
34113463}
34123464
34133465fn (mut g Gen) receiver_generic_call_context (left_type ast.Type, method_name string ) ([]ast.Type, ast.Fn) {
3466+ mut exact_method := ast.Fn{}
34143467 mut exact_method_exists := false
34153468 if left_type != 0 {
3416- if exact_method := g.table.sym (left_type).find_method (method_name) {
3417- exact_method_exists = exact_method.name == method_name
3418- } else if exact_method := g.table.find_alias_parent_exact_method (left_type, method_name) {
3419- exact_method_exists = exact_method.name == method_name
3469+ if method := g.receiver_exact_method_for_type (left_type, method_name) {
3470+ exact_method = method
3471+ exact_method_exists = true
34203472 }
34213473 }
3422- mut structured_method_for_exact := ast.Fn{}
34233474 mut has_structured_method_for_exact := false
34243475 if structured_method := g.table.find_structured_receiver_method_with_types (left_type,
34253476 method_name)
34263477 {
34273478 if exact_method_exists {
3428- structured_method_for_exact = structured_method.method
34293479 has_structured_method_for_exact = true
34303480 } else {
34313481 return structured_method.concrete_types.map (g.unwrap_generic (it )), structured_method.method
@@ -3434,6 +3484,9 @@ fn (mut g Gen) receiver_generic_call_context(left_type ast.Type, method_name str
34343484 rec_sym := g.table.final_sym (left_type)
34353485 mut receiver_concrete_types := []ast.Type{}
34363486 mut parent_method := ast.Fn{}
3487+ if has_structured_method_for_exact {
3488+ parent_method = exact_method
3489+ }
34373490 match rec_sym.info {
34383491 ast.Struct, ast.Interface, ast.SumType {
34393492 if rec_sym.info.concrete_types.len > 0 {
@@ -3445,8 +3498,7 @@ fn (mut g Gen) receiver_generic_call_context(left_type ast.Type, method_name str
34453498 if rec_sym.info.parent_type.has_flag (.generic) {
34463499 parent_sym := g.table.sym (rec_sym.info.parent_type)
34473500 if m := parent_sym.find_method (method_name) {
3448- if ! has_structured_method_for_exact
3449- || m.fkey () != structured_method_for_exact.fkey () {
3501+ if ! has_structured_method_for_exact {
34503502 parent_method = m
34513503 }
34523504 }
@@ -3457,8 +3509,7 @@ fn (mut g Gen) receiver_generic_call_context(left_type ast.Type, method_name str
34573509 if rec_sym.info.parent_idx > 0 {
34583510 parent_sym := g.table.sym (ast.idx_to_type (rec_sym.info.parent_idx))
34593511 if m := parent_sym.find_method (method_name) {
3460- if ! has_structured_method_for_exact
3461- || m.fkey () != structured_method_for_exact.fkey () {
3512+ if ! has_structured_method_for_exact {
34623513 parent_method = m
34633514 }
34643515 }
@@ -3477,8 +3528,7 @@ fn (mut g Gen) receiver_generic_call_context(left_type ast.Type, method_name str
34773528 if non_final_sym.info.parent_idx > 0 {
34783529 parent_sym := g.table.sym (ast.idx_to_type (non_final_sym.info.parent_idx))
34793530 if m := parent_sym.find_method (method_name) {
3480- if ! has_structured_method_for_exact
3481- || m.fkey () != structured_method_for_exact.fkey () {
3531+ if ! has_structured_method_for_exact {
34823532 parent_method = m
34833533 }
34843534 }
@@ -3490,8 +3540,7 @@ fn (mut g Gen) receiver_generic_call_context(left_type ast.Type, method_name str
34903540 receiver_concrete_types = non_final_sym.generic_types.map (g.unwrap_generic (it ))
34913541 parent_sym := g.table.sym (ast.idx_to_type (non_final_sym.parent_idx))
34923542 if m := parent_sym.find_method (method_name) {
3493- if ! has_structured_method_for_exact
3494- || m.fkey () != structured_method_for_exact.fkey () {
3543+ if ! has_structured_method_for_exact {
34953544 parent_method = m
34963545 }
34973546 }
@@ -5210,7 +5259,15 @@ fn (mut g Gen) method_call(node ast.CallExpr) {
52105259 }
52115260 }
52125261 concrete_types = concrete_types.filter (it != ast.void_type)
5213- mut name_fkey := g.resolve_method_decl_fkey_for_type (left_type, method_name)
5262+ mut name_fkey := ''
5263+ if _ := g.table.find_structured_receiver_method_with_types (left_type, method_name) {
5264+ if exact_method := g.receiver_exact_method_for_type (left_type, method_name) {
5265+ name_fkey = g.method_decl_fkey (exact_method)
5266+ }
5267+ }
5268+ if name_fkey == '' {
5269+ name_fkey = g.resolve_method_decl_fkey_for_type (left_type, method_name)
5270+ }
52145271 if name_fkey == '' {
52155272 name_fkey = g.method_decl_fkey (full_method)
52165273 }
0 commit comments