checker: tweak error messages for `or` block; use proper type names (#6377)
parent
f59b771c76
commit
14743458e5
|
@ -262,6 +262,7 @@ pub mut:
|
|||
return_type table.Type
|
||||
}
|
||||
|
||||
// break, continue
|
||||
pub struct BranchStmt {
|
||||
pub:
|
||||
tok token.Token
|
||||
|
|
|
@ -1509,12 +1509,6 @@ pub fn (mut c Checker) check_or_expr(mut or_expr ast.OrExpr, ret_type table.Type
|
|||
}
|
||||
mut last_stmt := or_expr.stmts[stmts_len - 1]
|
||||
if ret_type != table.void_type {
|
||||
if !(last_stmt is ast.Return || last_stmt is ast.BranchStmt || last_stmt is ast.ExprStmt) {
|
||||
expected_type_name := c.table.get_type_symbol(ret_type).name
|
||||
c.error('last statement in the `or {}` block should return `$expected_type_name`',
|
||||
or_expr.pos)
|
||||
return
|
||||
}
|
||||
match mut last_stmt {
|
||||
ast.ExprStmt {
|
||||
last_stmt.typ = c.expr(last_stmt.expr)
|
||||
|
@ -1523,8 +1517,8 @@ pub fn (mut c Checker) check_or_expr(mut or_expr ast.OrExpr, ret_type table.Type
|
|||
if type_fits || is_panic_or_exit {
|
||||
return
|
||||
}
|
||||
type_name := c.table.get_type_symbol(last_stmt.typ).name
|
||||
expected_type_name := c.table.get_type_symbol(ret_type).name
|
||||
type_name := c.table.type_to_str(last_stmt.typ)
|
||||
expected_type_name := c.table.type_to_str(ret_type.clear_flag(.optional))
|
||||
c.error('wrong return type `$type_name` in the `or {}` block, expected `$expected_type_name`',
|
||||
last_stmt.pos)
|
||||
return
|
||||
|
@ -1536,11 +1530,16 @@ pub fn (mut c Checker) check_or_expr(mut or_expr ast.OrExpr, ret_type table.Type
|
|||
return
|
||||
}
|
||||
}
|
||||
else {}
|
||||
}
|
||||
ast.Return {}
|
||||
else {
|
||||
expected_type_name := c.table.type_to_str(ret_type.clear_flag(.optional))
|
||||
c.error('last statement in the `or {}` block should be an expression of type `$expected_type_name` or exit parent scope',
|
||||
or_expr.pos)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn is_expr_panic_or_exit(expr ast.Expr) bool {
|
||||
match expr {
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
vlib/v/checker/tests/or_err.vv:4:6: error: last statement in the `or {}` block should be an expression of type `&int` or exit parent scope
|
||||
2 | return none
|
||||
3 | }
|
||||
4 | a := f() or {
|
||||
| ~~~
|
||||
5 | {}
|
||||
6 | }
|
||||
vlib/v/checker/tests/or_err.vv:11:2: error: wrong return type `rune` in the `or {}` block, expected `&int`
|
||||
9 | }
|
||||
10 | _ = f() or {
|
||||
11 | `.`
|
||||
| ~~~
|
||||
12 | }
|
||||
13 |
|
|
@ -0,0 +1,13 @@
|
|||
fn f() ?&int {
|
||||
return none
|
||||
}
|
||||
a := f() or {
|
||||
{}
|
||||
}
|
||||
_ = f() or {
|
||||
a
|
||||
}
|
||||
_ = f() or {
|
||||
`.`
|
||||
}
|
||||
|
|
@ -24,14 +24,19 @@ pub enum Language {
|
|||
js
|
||||
}
|
||||
|
||||
// Represents a type that only needs an identifier, e.g. int, array_int.
|
||||
// A pointer type `&T` would have a TypeSymbol `T`.
|
||||
// Note: For a Type, use Table.type_to_str(typ) not TypeSymbol.name.
|
||||
// Each TypeSymbol is entered into `Table.types`.
|
||||
// See also: Table.get_type_symbol.
|
||||
pub struct TypeSymbol {
|
||||
pub:
|
||||
parent_idx int
|
||||
pub mut:
|
||||
info TypeInfo
|
||||
kind Kind
|
||||
name string // the internal name of the type, i.e. `array_fixed_int_5`. See also .source_name below.
|
||||
source_name string // the original source name of the type, i.e. `[5]int`. Do not use this for logic, but just for formatting/errors.
|
||||
name string // the internal name of the type or underlying type, i.e. `array_fixed_int_5`. See also .source_name below.
|
||||
source_name string // the original source name of the type, i.e. `[5]int`.
|
||||
methods []Fn
|
||||
mod string
|
||||
is_public bool
|
||||
|
|
Loading…
Reference in New Issue