v.ast, v.checker: fix absent 'missing return' warning, when a function ended with a t.panic() call

pull/9824/head
Delyan Angelov 2021-04-20 11:49:06 +03:00
parent fe88a4460b
commit 9d8bda9eaf
No known key found for this signature in database
GPG Key ID: 66886C0F12D595ED
4 changed files with 36 additions and 3 deletions

View File

@ -431,6 +431,15 @@ pub fn (t &Table) find_type(name string) ?TypeSymbol {
return none return none
} }
pub const invalid_type_symbol = &TypeSymbol{
parent_idx: -1
language: .v
mod: 'builtin'
kind: .placeholder
name: 'InvalidType'
cname: 'InvalidType'
}
[inline] [inline]
pub fn (t &Table) get_type_symbol(typ Type) &TypeSymbol { pub fn (t &Table) get_type_symbol(typ Type) &TypeSymbol {
// println('get_type_symbol $typ') // println('get_type_symbol $typ')
@ -441,6 +450,7 @@ pub fn (t &Table) get_type_symbol(typ Type) &TypeSymbol {
// this should never happen // this should never happen
t.panic('get_type_symbol: invalid type (typ=$typ idx=$idx). Compiler bug. This should never happen. Please report the bug using `v bug file.v`. t.panic('get_type_symbol: invalid type (typ=$typ idx=$idx). Compiler bug. This should never happen. Please report the bug using `v bug file.v`.
') ')
return ast.invalid_type_symbol
} }
// get_final_type_symbol follows aliases until it gets to a "real" Type // get_final_type_symbol follows aliases until it gets to a "real" Type
@ -457,6 +467,7 @@ pub fn (t &Table) get_final_type_symbol(typ Type) &TypeSymbol {
} }
// this should never happen // this should never happen
t.panic('get_final_type_symbol: invalid type (typ=$typ idx=$idx). Compiler bug. This should never happen. Please report the bug using `v bug file.v`.') t.panic('get_final_type_symbol: invalid type (typ=$typ idx=$idx). Compiler bug. This should never happen. Please report the bug using `v bug file.v`.')
return ast.invalid_type_symbol
} }
[inline] [inline]

View File

@ -2511,7 +2511,7 @@ pub fn (mut c Checker) check_or_expr(or_expr ast.OrExpr, ret_type ast.Type, expr
fn is_expr_panic_or_exit(expr ast.Expr) bool { fn is_expr_panic_or_exit(expr ast.Expr) bool {
match expr { match expr {
ast.CallExpr { return expr.name in ['panic', 'exit'] } ast.CallExpr { return !expr.is_method && expr.name in ['panic', 'exit'] }
else { return false } else { return false }
} }
} }
@ -6584,7 +6584,7 @@ fn (mut c Checker) fn_decl(mut node ast.FnDecl) {
c.stmts(node.stmts) c.stmts(node.stmts)
node.has_return = c.returns || has_top_return(node.stmts) node.has_return = c.returns || has_top_return(node.stmts)
if node.language == .v && !node.no_body && node.return_type != ast.void_type && !node.has_return if node.language == .v && !node.no_body && node.return_type != ast.void_type && !node.has_return
&& node.name !in ['panic', 'exit'] { && (node.is_method || node.name !in ['panic', 'exit']) {
if c.inside_anon_fn { if c.inside_anon_fn {
c.error('missing return at the end of an anonymous function', node.pos) c.error('missing return at the end of an anonymous function', node.pos)
} else { } else {
@ -6605,7 +6605,7 @@ fn has_top_return(stmts []ast.Stmt) bool {
} }
} else if stmt is ast.ExprStmt { } else if stmt is ast.ExprStmt {
if stmt.expr is ast.CallExpr { if stmt.expr is ast.CallExpr {
if stmt.expr.name in ['panic', 'exit'] { if !stmt.expr.is_method && stmt.expr.name in ['panic', 'exit'] {
return true return true
} }
} }

View File

@ -3,3 +3,10 @@ vlib/v/checker/tests/function_missing_return_type.vv:1:1: error: missing return
| ~~~~~~~~~~ | ~~~~~~~~~~
2 | } 2 | }
3 | 3 |
vlib/v/checker/tests/function_missing_return_type.vv:12:1: error: missing return at end of function `abc`
10 | }
11 |
12 | fn (s Abc) abc() &int {
| ~~~~~~~~~~~~~~~~~~~~~
13 | if true {
14 | return &s.x

View File

@ -1,6 +1,21 @@
fn h() int { fn h() int {
} }
struct Abc {
x int
}
fn (s Abc) panic(message string) {
println('called ${@METHOD} with message: $message')
}
fn (s Abc) abc() &int {
if true {
return &s.x
}
s.panic(@FN)
}
fn main() { fn main() {
d := h() d := h()
println('$d') println('$d')