diff --git a/vlib/v/builder/builder.v b/vlib/v/builder/builder.v index e840afd7af..c99ed35300 100644 --- a/vlib/v/builder/builder.v +++ b/vlib/v/builder/builder.v @@ -70,9 +70,10 @@ pub fn (mut b Builder) front_stages(v_files []string) ? { util.timing_start('PARSE') b.parsed_files = parser.parse_files(v_files, b.table, b.pref, b.global_scope) b.parse_imports() - util.get_timers().show('SCAN') - util.get_timers().show('PARSE') - util.get_timers().show_if_exists('PARSE stmt') + mut timers := util.get_timers() + timers.show('SCAN') + timers.show('PARSE') + timers.show_if_exists('PARSE stmt') if b.pref.only_check_syntax { return error('stop_after_parser') } diff --git a/vlib/v/builder/compile.v b/vlib/v/builder/compile.v index 9ba322f3e3..dacd9b9216 100644 --- a/vlib/v/builder/compile.v +++ b/vlib/v/builder/compile.v @@ -43,7 +43,8 @@ pub fn compile(command string, pref &pref.Preferences) { .js { b.compile_js() } .native { b.compile_native() } } - util.get_timers().show_remaining() + mut timers := util.get_timers() + timers.show_remaining() if pref.is_stats { compilation_time_micros := 1 + sw.elapsed().microseconds() scompilation_time_ms := util.bold('${f64(compilation_time_micros) / 1000.0:6.3f}') diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 5a57057c9f..b754e85b30 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -2106,6 +2106,9 @@ pub fn (mut c Checker) method_call(mut call_expr ast.CallExpr) ast.Type { } if method.params[0].is_mut { to_lock, pos := c.fail_if_immutable(call_expr.left) + if !call_expr.left.is_lvalue() { + c.error('cannot pass expression as `mut`', call_expr.left.position()) + } // call_expr.is_mut = true if to_lock != '' && rec_share != .shared_t { c.error('$to_lock is `shared` and must be `lock`ed to be passed as `mut`', diff --git a/vlib/v/checker/tests/mut_receiver_lit.out b/vlib/v/checker/tests/mut_receiver_lit.out new file mode 100644 index 0000000000..e0cd49066d --- /dev/null +++ b/vlib/v/checker/tests/mut_receiver_lit.out @@ -0,0 +1,5 @@ +vlib/v/checker/tests/mut_receiver_lit.vv:10:1: error: cannot pass expression as `mut` + 8 | } + 9 | + 10 | Box{}.set(0) + | ~~~~~ diff --git a/vlib/v/checker/tests/mut_receiver_lit.vv b/vlib/v/checker/tests/mut_receiver_lit.vv new file mode 100644 index 0000000000..e015e715f2 --- /dev/null +++ b/vlib/v/checker/tests/mut_receiver_lit.vv @@ -0,0 +1,10 @@ +struct Box { +mut: + value int +} + +fn (mut box Box) set(value int) { + box.value = value +} + +Box{}.set(0) diff --git a/vlib/v/scanner/scanner.v b/vlib/v/scanner/scanner.v index 200c0cad67..b60deb9700 100644 --- a/vlib/v/scanner/scanner.v +++ b/vlib/v/scanner/scanner.v @@ -537,11 +537,12 @@ fn (mut s Scanner) end_of_file() token.Token { } pub fn (mut s Scanner) scan_all_tokens_in_buffer(mode CommentsMode) { - util.get_timers().measure_pause('PARSE') + mut timers := util.get_timers() + timers.measure_pause('PARSE') util.timing_start('SCAN') defer { util.timing_measure_cumulative('SCAN') - util.get_timers().measure_resume('PARSE') + timers.measure_resume('PARSE') } oldmode := s.comments_mode s.comments_mode = mode diff --git a/vlib/v/tests/method_call_chain_test.v b/vlib/v/tests/method_call_chain_test.v deleted file mode 100644 index b062f4b747..0000000000 --- a/vlib/v/tests/method_call_chain_test.v +++ /dev/null @@ -1,30 +0,0 @@ -struct Test { -mut: - val int -} - -// this must return a reference, or else you'll get a C error -// TODO: add a proper checker check for that case -fn new(x int) &Test { - return &Test{x} -} - -fn (mut t Test) inc() &Test { - t.val++ - return unsafe { t } -} - -fn (mut t Test) add(x int) &Test { - t.val += x - return unsafe { t } -} - -fn (mut t Test) div(x int) &Test { - t.val /= x - return unsafe { t } -} - -fn test_method_call_chains() { - mut x := new(4).inc().inc().inc().inc().add(4).div(2).inc() - assert x.val == 7 -} diff --git a/vlib/v/util/timers.v b/vlib/v/util/timers.v index 7a0b9662a4..725891c7dc 100644 --- a/vlib/v/util/timers.v +++ b/vlib/v/util/timers.v @@ -28,15 +28,18 @@ pub fn get_timers() &Timers { } pub fn timing_start(label string) { - get_timers().start(label) + mut t := get_timers() + t.start(label) } pub fn timing_measure(label string) { - get_timers().show(label) + mut t := get_timers() + t.show(label) } pub fn timing_measure_cumulative(label string) { - get_timers().measure_cumulative(label) + mut t := get_timers() + t.measure_cumulative(label) } pub fn timing_set_should_print(should_print bool) {