@@ -1069,13 +1069,6 @@ pub fn (mut c Checker) method_call(mut node ast.CallExpr) ast.Type {
10691069 left_type := c.expr (node.left)
10701070 c.expected_type = left_type
10711071 mut is_generic := left_type.has_flag (.generic)
1072- // x is Bar<T>, x.foo() -> x.foo<T>()
1073- if is_generic && node.concrete_types.len == 0 {
1074- rec_sym := c.table.sym (left_type)
1075- if rec_sym.info is ast.Struct {
1076- node.concrete_types = rec_sym.info.generic_types
1077- }
1078- }
10791072 node.left_type = left_type
10801073 // Set default values for .return_type & .receiver_type too,
10811074 // or there will be hard tRo diagnose 0 type panics in cgen.
@@ -1113,19 +1106,6 @@ pub fn (mut c Checker) method_call(mut node ast.CallExpr) ast.Type {
11131106 // c.error('`void` type has no methods', node.left.pos())
11141107 return ast.void_type
11151108 }
1116- mut concrete_types := []ast.Type{}
1117- for concrete_type in node.concrete_types {
1118- if concrete_type.has_flag (.generic) {
1119- concrete_types << c.unwrap_generic (concrete_type)
1120- } else {
1121- concrete_types << concrete_type
1122- }
1123- }
1124- if concrete_types.len > 0 {
1125- if c.table.register_fn_concrete_types (node.fkey (), concrete_types) {
1126- c.need_recheck_generic_fns = true
1127- }
1128- }
11291109 // TODO: remove this for actual methods, use only for compiler magic
11301110 // FIXME: Argument count != 1 will break these
11311111 if left_sym.kind == .array && method_name in array_builtin_methods {
@@ -1239,6 +1219,33 @@ pub fn (mut c Checker) method_call(mut node ast.CallExpr) ast.Type {
12391219 }
12401220 }
12411221 if has_method {
1222+ // x is Bar<T>, x.foo() -> x.foo<T>()
1223+ rec_sym := c.table.sym (node.left_type)
1224+ rec_is_generic := left_type.has_flag (.generic)
1225+ if rec_sym.info is ast.Struct {
1226+ if rec_is_generic && node.concrete_types.len == 0 {
1227+ node.concrete_types = rec_sym.info.generic_types
1228+ } else if ! rec_is_generic && rec_sym.info.concrete_types.len > 0
1229+ && node.concrete_types.len > 0
1230+ && rec_sym.info.concrete_types.len + node.concrete_types.len == method.generic_names.len {
1231+ t_concrete_types := node.concrete_types.clone ()
1232+ node.concrete_types = rec_sym.info.concrete_types
1233+ node.concrete_types << t_concrete_types
1234+ }
1235+ }
1236+ mut concrete_types := []ast.Type{}
1237+ for concrete_type in node.concrete_types {
1238+ if concrete_type.has_flag (.generic) {
1239+ concrete_types << c.unwrap_generic (concrete_type)
1240+ } else {
1241+ concrete_types << concrete_type
1242+ }
1243+ }
1244+ if concrete_types.len > 0 {
1245+ if c.table.register_fn_concrete_types (node.fkey (), concrete_types) {
1246+ c.need_recheck_generic_fns = true
1247+ }
1248+ }
12421249 node.is_noreturn = method.is_noreturn
12431250 node.is_ctor_new = method.is_ctor_new
12441251 if ! method.is_pub && ! c.pref.is_test && method.mod != c.mod {
0 commit comments