diff --git a/vlib/v/checker/fn.v b/vlib/v/checker/fn.v index c79256cb27..0bd49e7ed5 100644 --- a/vlib/v/checker/fn.v +++ b/vlib/v/checker/fn.v @@ -709,6 +709,7 @@ fn (mut c Checker) call_expr(mut node ast.CallExpr) ast.Type { old_inside_fn_arg := c.inside_fn_arg c.inside_fn_arg = true mut continue_check := true + node.left_type = left_type // Now call `method_call` or `fn_call` for specific checks. typ := if node.is_method { c.method_call(mut node, mut continue_check) @@ -1020,7 +1021,6 @@ fn (mut c Checker) fn_call(mut node ast.CallExpr, mut continue_check &bool) ast. if node.left is ast.AnonFn { // it was set to anon for checker errors, clear for gen node.name = '' - c.expr(mut node.left) left := node.left as ast.AnonFn if left.typ != ast.no_type { anon_fn_sym := c.table.sym(left.typ) @@ -1039,7 +1039,6 @@ fn (mut c Checker) fn_call(mut node ast.CallExpr, mut continue_check &bool) ast. } } if !found && node.left is ast.IndexExpr { - c.expr(mut node.left) left := node.left as ast.IndexExpr sym := c.table.final_sym(left.left_type) if sym.info is ast.Array { @@ -1077,7 +1076,6 @@ fn (mut c Checker) fn_call(mut node ast.CallExpr, mut continue_check &bool) ast. } } if !found && node.left is ast.CallExpr { - c.expr(mut node.left) left := node.left as ast.CallExpr if left.return_type != 0 { sym := c.table.sym(left.return_type) @@ -1984,7 +1982,7 @@ fn (mut c Checker) method_call(mut node ast.CallExpr, mut continue_check &bool) } } } - left_type := c.expr(mut node.left) + left_type := node.left_type if left_type == ast.void_type { // c.error('cannot call a method using an invalid expression', node.pos) continue_check = false diff --git a/vlib/v/checker/tests/generics_struct_init_err.out b/vlib/v/checker/tests/generics_struct_init_err.out index 6d0723a0da..d768e9a4b2 100644 --- a/vlib/v/checker/tests/generics_struct_init_err.out +++ b/vlib/v/checker/tests/generics_struct_init_err.out @@ -5,13 +5,6 @@ vlib/v/checker/tests/generics_struct_init_err.vv:14:2: notice: uninitialized `fn | ~~~~~~~~~~~~~~~~~ 15 | } 16 | -vlib/v/checker/tests/generics_struct_init_err.vv:58:8: error: cannot initialize builtin type `FnHolder1[neg]` - 56 | ret = holder_call_12(neg, 3) - 57 | assert ret == -3 - 58 | ret = FnHolder1{neg}.call(4) - | ~~~~~~~~~~~~~~ - 59 | assert ret == -4 - 60 | vlib/v/checker/tests/generics_struct_init_err.vv:67:8: error: could not infer generic type `T` in generic struct `FnHolder2[T]` 65 | ret = holder_call_22(neg, 5) 66 | assert ret == -5 diff --git a/vlib/v/checker/tests/void_method_call.out b/vlib/v/checker/tests/void_method_call.out index 3682055a1b..bfb502c44b 100644 --- a/vlib/v/checker/tests/void_method_call.out +++ b/vlib/v/checker/tests/void_method_call.out @@ -1,4 +1,4 @@ -vlib/v/checker/tests/void_method_call.vv:5:14: cgen error: checker bug; CallExpr.left_type is 0 in method_call +vlib/v/checker/tests/void_method_call.vv:5:14: cgen error: checker bug; CallExpr.receiver_type is 0 in method_call 3 | 4 | fn main() { 5 | simple_fn().method() diff --git a/vlib/v/tests/fns/call_nested_test.v b/vlib/v/tests/fns/call_nested_test.v new file mode 100644 index 0000000000..04b1fabacf --- /dev/null +++ b/vlib/v/tests/fns/call_nested_test.v @@ -0,0 +1,42 @@ +module main + +@[heap] +struct MyStruct { + a int +} + +fn (m &MyStruct) set(s string) !&MyStruct { + return m +} + +fn test_main() { + mut m := MyStruct{} + x := m.set('2')! + .set('2')! + .set('2')! + .set('2')! + .set('2')! + .set('2')! + .set('2')! + .set('2')! + .set('2')! + .set('2')! + .set('2')! + .set('2')! + .set('2')! + .set('2')! + .set('2')! + .set('2')! + .set('2')! + .set('2')! + .set('2')! + .set('2')! + .set('2')! + .set('2')! + .set('2')! + .set('2')! + .set('2')! + .set('2')! + .set('2')! + dump(x) +}