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
|
return_type table.Type
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// break, continue
|
||||||
pub struct BranchStmt {
|
pub struct BranchStmt {
|
||||||
pub:
|
pub:
|
||||||
tok token.Token
|
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]
|
mut last_stmt := or_expr.stmts[stmts_len - 1]
|
||||||
if ret_type != table.void_type {
|
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 {
|
match mut last_stmt {
|
||||||
ast.ExprStmt {
|
ast.ExprStmt {
|
||||||
last_stmt.typ = c.expr(last_stmt.expr)
|
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 {
|
if type_fits || is_panic_or_exit {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
type_name := c.table.get_type_symbol(last_stmt.typ).name
|
type_name := c.table.type_to_str(last_stmt.typ)
|
||||||
expected_type_name := c.table.get_type_symbol(ret_type).name
|
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`',
|
c.error('wrong return type `$type_name` in the `or {}` block, expected `$expected_type_name`',
|
||||||
last_stmt.pos)
|
last_stmt.pos)
|
||||||
return
|
return
|
||||||
|
@ -1536,10 +1530,15 @@ pub fn (mut c Checker) check_or_expr(mut or_expr ast.OrExpr, ret_type table.Type
|
||||||
return
|
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
|
return
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_expr_panic_or_exit(expr ast.Expr) bool {
|
fn is_expr_panic_or_exit(expr ast.Expr) bool {
|
||||||
|
|
|
@ -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
|
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 struct TypeSymbol {
|
||||||
pub:
|
pub:
|
||||||
parent_idx int
|
parent_idx int
|
||||||
pub mut:
|
pub mut:
|
||||||
info TypeInfo
|
info TypeInfo
|
||||||
kind Kind
|
kind Kind
|
||||||
name string // the internal name of the type, i.e. `array_fixed_int_5`. See also .source_name below.
|
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`. Do not use this for logic, but just for formatting/errors.
|
source_name string // the original source name of the type, i.e. `[5]int`.
|
||||||
methods []Fn
|
methods []Fn
|
||||||
mod string
|
mod string
|
||||||
is_public bool
|
is_public bool
|
||||||
|
|
Loading…
Reference in New Issue