checker: add error for `if c >= A && c <= Z {` in non generic functions
parent
96a9faf2fd
commit
4b3c3d9082
|
@ -89,6 +89,7 @@ pub mut:
|
|||
inside_defer bool // true inside `defer {}` blocks
|
||||
inside_fn_arg bool // `a`, `b` in `a.f(b)`
|
||||
inside_ct_attr bool // true inside `[if expr]`
|
||||
inside_x_is_type bool // true inside the Type expression of `if x is Type {`
|
||||
inside_comptime_for_field bool
|
||||
skip_flags bool // should `#flag` and `#include` be skipped
|
||||
fn_level int // 0 for the top level, 1 for `fn abc() {}`, 2 for a nested fn, etc
|
||||
|
@ -156,6 +157,7 @@ fn (mut c Checker) reset_checker_state_at_start_of_new_file() {
|
|||
c.inside_defer = false
|
||||
c.inside_fn_arg = false
|
||||
c.inside_ct_attr = false
|
||||
c.inside_x_is_type = false
|
||||
c.skip_flags = false
|
||||
c.fn_level = 0
|
||||
c.expr_level = 0
|
||||
|
@ -1605,9 +1607,10 @@ fn (mut c Checker) assert_stmt(node ast.AssertStmt) {
|
|||
|
||||
fn (mut c Checker) block(node ast.Block) {
|
||||
if node.is_unsafe {
|
||||
prev_unsafe := c.inside_unsafe
|
||||
c.inside_unsafe = true
|
||||
c.stmts(node.stmts)
|
||||
c.inside_unsafe = false
|
||||
c.inside_unsafe = prev_unsafe
|
||||
} else {
|
||||
c.stmts(node.stmts)
|
||||
}
|
||||
|
@ -2021,7 +2024,9 @@ pub fn (mut c Checker) expr(node_ ast.Expr) ast.Type {
|
|||
c.error('incorrect use of compile-time type', node.pos)
|
||||
}
|
||||
ast.EmptyExpr {
|
||||
print_backtrace()
|
||||
c.error('checker.expr(): unhandled EmptyExpr', token.Pos{})
|
||||
return ast.void_type
|
||||
}
|
||||
ast.CTempVar {
|
||||
return node.typ
|
||||
|
@ -2269,6 +2274,11 @@ pub fn (mut c Checker) expr(node_ ast.Expr) ast.Type {
|
|||
return c.struct_init(mut node)
|
||||
}
|
||||
ast.TypeNode {
|
||||
if !c.inside_x_is_type && node.typ.has_flag(.generic) && unsafe { c.table.cur_fn != 0 }
|
||||
&& c.table.cur_fn.generic_names.len == 0 {
|
||||
c.error('unexpected generic variable in non-generic function `$c.table.cur_fn.name`',
|
||||
node.pos)
|
||||
}
|
||||
return node.typ
|
||||
}
|
||||
ast.TypeOf {
|
||||
|
|
|
@ -9,7 +9,9 @@ import v.util
|
|||
import v.pkgconfig
|
||||
|
||||
fn (mut c Checker) comptime_call(mut node ast.ComptimeCall) ast.Type {
|
||||
if node.left !is ast.EmptyExpr {
|
||||
node.left_type = c.expr(node.left)
|
||||
}
|
||||
if node.method_name == 'compile_error' {
|
||||
c.error(node.args_var, node.pos)
|
||||
return ast.void_type
|
||||
|
|
|
@ -165,10 +165,13 @@ fn (mut c Checker) for_stmt(mut node ast.ForStmt) {
|
|||
c.in_for_count++
|
||||
prev_loop_label := c.loop_label
|
||||
c.expected_type = ast.bool_type
|
||||
if node.cond !is ast.EmptyExpr {
|
||||
typ := c.expr(node.cond)
|
||||
if !node.is_inf && typ.idx() != ast.bool_type_idx && !c.pref.translated && !c.file.is_translated {
|
||||
if !node.is_inf && typ.idx() != ast.bool_type_idx && !c.pref.translated
|
||||
&& !c.file.is_translated {
|
||||
c.error('non-bool used as for condition', node.pos)
|
||||
}
|
||||
}
|
||||
if mut node.cond is ast.InfixExpr {
|
||||
if node.cond.op == .key_is {
|
||||
if node.cond.right is ast.TypeNode && node.cond.left in [ast.Ident, ast.SelectorExpr] {
|
||||
|
|
|
@ -12,7 +12,14 @@ pub fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type {
|
|||
mut left_type := c.expr(node.left)
|
||||
node.left_type = left_type
|
||||
c.expected_type = left_type
|
||||
|
||||
if node.op == .key_is {
|
||||
c.inside_x_is_type = true
|
||||
}
|
||||
mut right_type := c.expr(node.right)
|
||||
if node.op == .key_is {
|
||||
c.inside_x_is_type = false
|
||||
}
|
||||
node.right_type = right_type
|
||||
if left_type.is_number() && !left_type.is_ptr()
|
||||
&& right_type in [ast.int_literal_type, ast.float_literal_type] {
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
vlib/v/checker/tests/generic_type_name_in_non_generic_function.vv:3:10: error: unexpected generic variable in non-generic function `main`
|
||||
1 | fn main() {
|
||||
2 | c := u8(`D`)
|
||||
3 | if c >= A && c <= Z {
|
||||
| ^
|
||||
4 | println('yes')
|
||||
5 | } else {
|
|
@ -0,0 +1,8 @@
|
|||
fn main() {
|
||||
c := u8(`D`)
|
||||
if c >= A && c <= Z {
|
||||
println('yes')
|
||||
} else {
|
||||
println('no')
|
||||
}
|
||||
}
|
|
@ -252,7 +252,7 @@ pub fn (mut ctx Context) file(f_path string) Result {
|
|||
return Result{}
|
||||
}
|
||||
content_type := vweb.mime_types[ext]
|
||||
if content_type.len == O {
|
||||
if content_type.len == 0 {
|
||||
eprintln('no MIME type found for extension $ext')
|
||||
ctx.server_error(500)
|
||||
} else {
|
||||
|
|
Loading…
Reference in New Issue