@@ -1158,14 +1158,22 @@ fn (mut g Gen) change_comptime_args(func ast.Fn, mut node_ ast.CallExpr, concret
11581158 return comptime_args
11591159}
11601160
1161- fn (mut g Gen) method_call (node ast.CallExpr) {
1162- // TODO: there are still due to unchecked exprs (opt/some fn arg )
1163- if node. left_type == 0 {
1164- g. checker_bug ( 'CallExpr.left_type is 0 in method_call' , node.pos)
1161+ fn (mut g Gen) resolve_receiver_name (node ast.CallExpr, unwrapped_rec_type ast.Type, final_left_sym ast.TypeSymbol, left_sym ast.TypeSymbol, typ_sym ast.TypeSymbol) string {
1162+ mut receiver_type_name := util. no_dots (g. cc_type (unwrapped_rec_type, false ) )
1163+ if final_left_sym. kind == . map && node.name in [ 'clone' , 'move' ] {
1164+ receiver_type_name = 'map'
11651165 }
1166- if node.receiver_type == 0 {
1167- g.checker_bug ('CallExpr.receiver_type is 0 in method_call' , node.pos)
1166+ if final_left_sym.kind == .array && ! (left_sym.kind == .alias && left_sym.has_method (node.name))
1167+ && node.name in ['clear' , 'repeat' , 'sort_with_compare' , 'sorted_with_compare' , 'free' , 'push_many' , 'trim' , 'first' , 'last' , 'pop' , 'clone' , 'reverse' , 'slice' , 'pointers' ] {
1168+ if ! (left_sym.info is ast.Alias && typ_sym.has_method (node.name)) {
1169+ // `array_Xyz_clone` => `array_clone`
1170+ receiver_type_name = 'array'
1171+ }
11681172 }
1173+ return receiver_type_name
1174+ }
1175+
1176+ fn (mut g Gen) resolve_receiver_type (node ast.CallExpr) (ast.Type, & ast.TypeSymbol) {
11691177 left_type := g.unwrap_generic (node.left_type)
11701178 mut unwrapped_rec_type := node.receiver_type
11711179 if g.cur_fn != unsafe { nil } && g.cur_fn.generic_names.len > 0 { // in generic fn
@@ -1215,9 +1223,23 @@ fn (mut g Gen) method_call(node ast.CallExpr) {
12151223 unwrapped_rec_type = node.from_embed_types.last ()
12161224 typ_sym = g.table.sym (unwrapped_rec_type)
12171225 }
1226+ return unwrapped_rec_type, typ_sym
1227+ }
1228+
1229+ fn (mut g Gen) method_call (node ast.CallExpr) {
1230+ // TODO: there are still due to unchecked exprs (opt/some fn arg)
1231+ if node.left_type == 0 {
1232+ g.checker_bug ('CallExpr.left_type is 0 in method_call' , node.pos)
1233+ }
1234+ if node.receiver_type == 0 {
1235+ g.checker_bug ('CallExpr.receiver_type is 0 in method_call' , node.pos)
1236+ }
1237+ left_type := g.unwrap_generic (node.left_type)
1238+ mut unwrapped_rec_type , typ_sym := g.resolve_receiver_type (node)
1239+
12181240 rec_cc_type := g.cc_type (unwrapped_rec_type, false )
12191241 mut receiver_type_name := util.no_dots (rec_cc_type)
1220- if mut typ_sym.info is ast.Interface && typ_sym.info.defines_method (node.name) {
1242+ if typ_sym.info is ast.Interface && typ_sym.info.defines_method (node.name) {
12211243 // Speaker_name_table[s._interface_idx].speak(s._object)
12221244 $if debug_interface_method_call ? {
12231245 eprintln ('>>> interface typ_sym.name: ${typ_sym.name} | receiver_type_name: ${receiver_type_name} | pos: ${node.pos} ' )
@@ -1306,15 +1328,11 @@ fn (mut g Gen) method_call(node ast.CallExpr) {
13061328 g.get_free_method (rec_type)
13071329 }
13081330 mut has_cast := false
1309- if final_left_sym. kind == . map && node.name in [ 'clone' , 'move' ] {
1310- receiver_type_name = 'map'
1311- }
1331+
1332+ receiver_type_name = g. resolve_receiver_name (node, unwrapped_rec_type, final_left_sym,
1333+ left_sym, typ_sym)
13121334 if final_left_sym.kind == .array && ! (left_sym.kind == .alias && left_sym.has_method (node.name))
13131335 && node.name in ['clear' , 'repeat' , 'sort_with_compare' , 'sorted_with_compare' , 'free' , 'push_many' , 'trim' , 'first' , 'last' , 'pop' , 'clone' , 'reverse' , 'slice' , 'pointers' ] {
1314- if ! (left_sym.info is ast.Alias && typ_sym.has_method (node.name)) {
1315- // `array_Xyz_clone` => `array_clone`
1316- receiver_type_name = 'array'
1317- }
13181336 if node.name in ['last' , 'first' , 'pop' ] {
13191337 return_type_str := g.typ (node.return_type)
13201338 has_cast = true
0 commit comments