From 64c0645bcb59546bebd51436d37ec48a7defd571 Mon Sep 17 00:00:00 2001 From: Joe Conigliaro Date: Mon, 28 Dec 2020 20:09:43 +1100 Subject: [PATCH] checker: error when trying to propagate optional call in return stmt with ? --- vlib/v/checker/checker.v | 8 ++++++++ vlib/v/gen/cgen.v | 9 +++++++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 67b204070a..95051a003c 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -2028,6 +2028,14 @@ pub fn (mut c Checker) return_stmt(mut return_stmt ast.Return) { pos) } } + if exp_is_optional && return_stmt.exprs.len > 0 { + expr0 := return_stmt.exprs[0] + if expr0 is ast.CallExpr { + if expr0.or_block.kind == .propagate { + c.error('`?` is not needed, use `return ${expr0.name}()`', expr0.pos) + } + } + } } pub fn (mut c Checker) const_decl(mut node ast.ConstDecl) { diff --git a/vlib/v/gen/cgen.v b/vlib/v/gen/cgen.v index d972f2d66f..4ae1da4196 100644 --- a/vlib/v/gen/cgen.v +++ b/vlib/v/gen/cgen.v @@ -4101,7 +4101,7 @@ fn (mut g Gen) return_statement(node ast.Return) { } } // regular cases - if fn_return_is_multi { // not_optional_none { //&& !fn_return_is_optional { + if fn_return_is_multi && node.exprs.len > 0 && !g.expr_is_multi_return_call(node.exprs[0]) { // not_optional_none { //&& !fn_return_is_optional { // typ_sym := g.table.get_type_symbol(g.fn_decl.return_type) // mr_info := typ_sym.info as table.MultiReturn mut styp := '' @@ -4182,7 +4182,12 @@ fn (mut g Gen) return_statement(node ast.Return) { // normal return return_sym := g.table.get_type_symbol(node.types[0]) // `return opt_ok(expr)` for functions that expect an optional - if fn_return_is_optional && !node.types[0].has_flag(.optional) && return_sym.name != 'Option' { + mut expr_type_is_opt := node.types[0].has_flag(.optional) + expr0 := node.exprs[0] + if expr0 is ast.CallExpr { + expr_type_is_opt = expr0.return_type.has_flag(.optional) + } + if fn_return_is_optional && !expr_type_is_opt && return_sym.name != 'Option' { styp := g.base_type(g.fn_decl.return_type) opt_type := g.typ(g.fn_decl.return_type) // Create a tmp for this option