@@ -533,6 +533,39 @@ fn (mut g Gen) specialized_method_name_from_receiver(method ast.Fn, concrete_rec
533533 return g.generic_fn_name (specialization_types, base_name)
534534}
535535
536+ fn (mut g Gen) specialized_method_name_from_receiver_context (method ast.Fn, receiver_concrete_types []ast.Type, parent_method ast.Fn, base_name string ) string {
537+ if receiver_concrete_types.len == 0 || method.params.len == 0 {
538+ return base_name
539+ }
540+ method_receiver_generic_names := g.table.generic_type_names (method.params[0 ].typ)
541+ parent_receiver_generic_names := if parent_method.params.len > 0 {
542+ g.table.generic_type_names (parent_method.params[0 ].typ)
543+ } else {
544+ []string {}
545+ }
546+ full_method := if parent_method.generic_names.len > method.generic_names.len
547+ || (method_receiver_generic_names.len == 0 && parent_receiver_generic_names.len > 0 ) {
548+ parent_method
549+ } else {
550+ method
551+ }
552+ receiver_generic_names := g.table.generic_type_names (full_method.params[0 ].typ)
553+ if receiver_generic_names.len == 0 {
554+ if full_method.generic_names.len != receiver_concrete_types.len {
555+ return base_name
556+ }
557+ } else if full_method.generic_names.len > 0
558+ && (full_method.generic_names.len != receiver_generic_names.len
559+ || full_method.generic_names != receiver_generic_names) {
560+ return base_name
561+ }
562+ specialized_suffix := g.generic_fn_name (receiver_concrete_types, '' )
563+ if specialized_suffix != '' && base_name.ends_with (specialized_suffix) {
564+ return base_name
565+ }
566+ return g.generic_fn_name (receiver_concrete_types, base_name)
567+ }
568+
536569fn (mut g Gen) recover_method_call_concrete_types_from_name (raw_method_name string , method_name string , receiver_type ast.Type, method_for_generics ast.Fn, parent_generic_method ast.Fn) []ast.Type {
537570 if raw_method_name == '' || method_name == ''
538571 || ! raw_method_name.starts_with (method_name + '_T_' ) {
@@ -2836,17 +2869,16 @@ fn (mut g Gen) resolve_return_type(node ast.CallExpr) ast.Type {
28362869 func := left_sym.find_method_with_generic_parent (node.name) or {
28372870 g.table.find_method (left_sym, node.name) or { return ast.void_type }
28382871 }
2839- receiver_concrete_types , parent_method := g.receiver_generic_call_context (left_type,
2840- node.name)
28412872 if func.return_type != 0 && ! func.return_type.has_flag (.generic)
2842- && ! g.type_has_unresolved_generic_parts (func.return_type)
2843- && ! (receiver_concrete_types.len > 0 && parent_method.params.len > 0 ) {
2873+ && ! g.type_has_unresolved_generic_parts (func.return_type) {
28442874 return if node.or_block.kind == .absent {
28452875 func.return_type
28462876 } else {
28472877 func.return_type.clear_option_and_result ()
28482878 }
28492879 }
2880+ receiver_concrete_types , parent_method := g.receiver_generic_call_context (left_type,
2881+ node.name)
28502882 if func.generic_names.len > 0 {
28512883 mut concrete_types := if node.concrete_types.len == func.generic_names.len
28522884 && node.concrete_types.all (it != 0 && ! it .has_flag (.generic)
@@ -4712,7 +4744,8 @@ fn (mut g Gen) method_call(node ast.CallExpr) {
47124744 method_for_generics.generic_names.clone ()
47134745 }
47144746 if has_method {
4715- name = g.specialized_method_name_from_receiver (full_method, receiver_type, name)
4747+ name = g.specialized_method_name_from_receiver_context (full_method,
4748+ receiver_concrete_types, parent_generic_method, name)
47164749 }
47174750 if has_method && full_method_generic_names_len == 0 {
47184751 concrete_types = []ast.Type{}
0 commit comments