v.ast, v.checker: fix absent 'missing return' warning, when a function ended with a t.panic() call
parent
fe88a4460b
commit
9d8bda9eaf
|
@ -431,6 +431,15 @@ pub fn (t &Table) find_type(name string) ?TypeSymbol {
|
|||
return none
|
||||
}
|
||||
|
||||
pub const invalid_type_symbol = &TypeSymbol{
|
||||
parent_idx: -1
|
||||
language: .v
|
||||
mod: 'builtin'
|
||||
kind: .placeholder
|
||||
name: 'InvalidType'
|
||||
cname: 'InvalidType'
|
||||
}
|
||||
|
||||
[inline]
|
||||
pub fn (t &Table) get_type_symbol(typ Type) &TypeSymbol {
|
||||
// println('get_type_symbol $typ')
|
||||
|
@ -441,6 +450,7 @@ pub fn (t &Table) get_type_symbol(typ Type) &TypeSymbol {
|
|||
// 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`.
|
||||
')
|
||||
return ast.invalid_type_symbol
|
||||
}
|
||||
|
||||
// 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
|
||||
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]
|
||||
|
|
|
@ -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 {
|
||||
match expr {
|
||||
ast.CallExpr { return expr.name in ['panic', 'exit'] }
|
||||
ast.CallExpr { return !expr.is_method && expr.name in ['panic', 'exit'] }
|
||||
else { return false }
|
||||
}
|
||||
}
|
||||
|
@ -6584,7 +6584,7 @@ fn (mut c Checker) fn_decl(mut node ast.FnDecl) {
|
|||
c.stmts(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
|
||||
&& node.name !in ['panic', 'exit'] {
|
||||
&& (node.is_method || node.name !in ['panic', 'exit']) {
|
||||
if c.inside_anon_fn {
|
||||
c.error('missing return at the end of an anonymous function', node.pos)
|
||||
} else {
|
||||
|
@ -6605,7 +6605,7 @@ fn has_top_return(stmts []ast.Stmt) bool {
|
|||
}
|
||||
} else if stmt is ast.ExprStmt {
|
||||
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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,3 +3,10 @@ vlib/v/checker/tests/function_missing_return_type.vv:1:1: error: missing return
|
|||
| ~~~~~~~~~~
|
||||
2 | }
|
||||
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
|
||||
|
|
|
@ -1,6 +1,21 @@
|
|||
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() {
|
||||
d := h()
|
||||
println('$d')
|
||||
|
|
Loading…
Reference in New Issue