From 3f00ff465b3e3d6a8e5f4aedbff4b99344ff75a9 Mon Sep 17 00:00:00 2001 From: Lukas Neubert Date: Sat, 5 Jun 2021 22:01:58 +0200 Subject: [PATCH] checker: check or block inside println calls (#10354) --- vlib/v/checker/checker.v | 1 + .../tests/optional_in_println_mismatch.out | 6 ++++++ .../tests/optional_in_println_mismatch.vv | 7 +++++++ vlib/v/parser/parser.v | 17 ----------------- .../generics_return_generics_struct_test.v | 2 +- 5 files changed, 15 insertions(+), 18 deletions(-) create mode 100644 vlib/v/checker/tests/optional_in_println_mismatch.out create mode 100644 vlib/v/checker/tests/optional_in_println_mismatch.vv diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 9da8041769..bfc5b8d39c 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -2416,6 +2416,7 @@ pub fn (mut c Checker) fn_call(mut call_expr ast.CallExpr) ast.Type { c.inside_println_arg = true c.expected_type = ast.string_type call_expr.args[0].typ = c.expr(call_expr.args[0].expr) + _ := c.check_expr_opt_call(call_expr.args[0].expr, call_expr.args[0].typ) if call_expr.args[0].typ.is_void() { c.error('`$fn_name` can not print void expressions', call_expr.pos) } diff --git a/vlib/v/checker/tests/optional_in_println_mismatch.out b/vlib/v/checker/tests/optional_in_println_mismatch.out new file mode 100644 index 0000000000..8f1358660c --- /dev/null +++ b/vlib/v/checker/tests/optional_in_println_mismatch.out @@ -0,0 +1,6 @@ +vlib/v/checker/tests/optional_in_println_mismatch.vv:6:23: error: wrong return type `string` in the `or {}` block, expected `int` + 4 | + 5 | fn main() { + 6 | println(funcy() or { '' }) + | ~~ + 7 | } diff --git a/vlib/v/checker/tests/optional_in_println_mismatch.vv b/vlib/v/checker/tests/optional_in_println_mismatch.vv new file mode 100644 index 0000000000..fd3d067f76 --- /dev/null +++ b/vlib/v/checker/tests/optional_in_println_mismatch.vv @@ -0,0 +1,7 @@ +fn funcy() ?int { + return none +} + +fn main() { + println(funcy() or { '' }) +} diff --git a/vlib/v/parser/parser.v b/vlib/v/parser/parser.v index b2aa87689c..1529bddef9 100644 --- a/vlib/v/parser/parser.v +++ b/vlib/v/parser/parser.v @@ -181,10 +181,6 @@ pub fn parse_file(path string, table &ast.Table, comments_mode scanner.CommentsM // the parser gives feedback to the scanner about toplevel statements, so that the scanner can skip // all the tricky inner comments. This is needed because we do not have a good general solution // for handling them, and should be removed when we do (the general solution is also needed for vfmt) - // println('parse_file("$path")') - // text := os.read_file(path) or { - // panic(err) - // } mut p := Parser{ scanner: scanner.new_scanner_file(path, comments_mode, pref) comments_mode: comments_mode @@ -274,7 +270,6 @@ pub fn (mut p Parser) parse() &ast.File { p.check_unused_imports() break } - // println('stmt at ' + p.tok.str()) stmt := p.top_stmt() // clear the attributes after each statement if !(stmt is ast.ExprStmt && (stmt as ast.ExprStmt).expr is ast.Comment) { @@ -282,10 +277,7 @@ pub fn (mut p Parser) parse() &ast.File { } stmts << stmt } - // println('nr stmts = $stmts.len') - // println(stmts[0]) p.scope.end_pos = p.tok.pos - // return &ast.File{ path: p.file_name path_base: p.file_base @@ -343,7 +335,6 @@ pub fn parse_files(paths []string, table &ast.Table, pref &pref.Preferences, glo $if time_parsing ? { timers.should_print = true } - // println('nr_cpus= $nr_cpus') $if macos { /* if pref.is_parallel && paths[0].contains('/array.v') { @@ -367,10 +358,8 @@ pub fn parse_files(paths []string, table &ast.Table, pref &pref.Preferences, glo } */ } - // /////////////// mut files := []&ast.File{} for path in paths { - // println('parse_files $path') timers.start('parse_file $path') files << parse_file(path, table, .skip_comments, pref, global_scope) timers.show('parse_file $path') @@ -414,10 +403,8 @@ pub fn (mut p Parser) close_scope() { pub fn (mut p Parser) parse_block() []ast.Stmt { p.open_scope() - // println('parse block') stmts := p.parse_block_no_scope(false) p.close_scope() - // println('nr exprs in block = $exprs.len') return stmts } @@ -2089,7 +2076,6 @@ pub fn (mut p Parser) name_expr() ast.Expr { return node } else { // fn call - // println('calling $p.tok.lit') if is_optional { p.error_with_pos('unexpected $p.prev_tok', p.prev_tok.position()) } @@ -2136,10 +2122,8 @@ pub fn (mut p Parser) name_expr() ast.Expr { } else { enum_name = p.imported_symbols[enum_name] or { p.prepend_mod(enum_name) } } - // p.warn('Color.green $enum_name ' + p.prepend_mod(enum_name) + 'mod=$mod') p.check(.dot) val := p.check_name() - // println('enum val $enum_name . $val') p.expr_mod = '' return ast.EnumVal{ enum_name: enum_name @@ -3178,7 +3162,6 @@ fn (mut p Parser) assoc() ast.Assoc { } } v.is_used = true - // println('assoc var $name typ=$var.typ') mut fields := []string{} mut vals := []ast.Expr{} p.check(.pipe) diff --git a/vlib/v/tests/generics_return_generics_struct_test.v b/vlib/v/tests/generics_return_generics_struct_test.v index 0252bf0517..bcfee98a73 100644 --- a/vlib/v/tests/generics_return_generics_struct_test.v +++ b/vlib/v/tests/generics_return_generics_struct_test.v @@ -121,6 +121,6 @@ pub fn iter_data(data []T) Iterator { fn test_generics_return_generic_struct_from_fn() { mut it := iter_data([1, 2, 3]) - println(it.next()) + println(it.next() or { -1 }) assert '$it.next()' == 'Option(1)' }