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_defer bool // true inside `defer {}` blocks
|
||||||
inside_fn_arg bool // `a`, `b` in `a.f(b)`
|
inside_fn_arg bool // `a`, `b` in `a.f(b)`
|
||||||
inside_ct_attr bool // true inside `[if expr]`
|
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
|
inside_comptime_for_field bool
|
||||||
skip_flags bool // should `#flag` and `#include` be skipped
|
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
|
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_defer = false
|
||||||
c.inside_fn_arg = false
|
c.inside_fn_arg = false
|
||||||
c.inside_ct_attr = false
|
c.inside_ct_attr = false
|
||||||
|
c.inside_x_is_type = false
|
||||||
c.skip_flags = false
|
c.skip_flags = false
|
||||||
c.fn_level = 0
|
c.fn_level = 0
|
||||||
c.expr_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) {
|
fn (mut c Checker) block(node ast.Block) {
|
||||||
if node.is_unsafe {
|
if node.is_unsafe {
|
||||||
|
prev_unsafe := c.inside_unsafe
|
||||||
c.inside_unsafe = true
|
c.inside_unsafe = true
|
||||||
c.stmts(node.stmts)
|
c.stmts(node.stmts)
|
||||||
c.inside_unsafe = false
|
c.inside_unsafe = prev_unsafe
|
||||||
} else {
|
} else {
|
||||||
c.stmts(node.stmts)
|
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)
|
c.error('incorrect use of compile-time type', node.pos)
|
||||||
}
|
}
|
||||||
ast.EmptyExpr {
|
ast.EmptyExpr {
|
||||||
|
print_backtrace()
|
||||||
c.error('checker.expr(): unhandled EmptyExpr', token.Pos{})
|
c.error('checker.expr(): unhandled EmptyExpr', token.Pos{})
|
||||||
|
return ast.void_type
|
||||||
}
|
}
|
||||||
ast.CTempVar {
|
ast.CTempVar {
|
||||||
return node.typ
|
return node.typ
|
||||||
|
@ -2269,6 +2274,11 @@ pub fn (mut c Checker) expr(node_ ast.Expr) ast.Type {
|
||||||
return c.struct_init(mut node)
|
return c.struct_init(mut node)
|
||||||
}
|
}
|
||||||
ast.TypeNode {
|
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
|
return node.typ
|
||||||
}
|
}
|
||||||
ast.TypeOf {
|
ast.TypeOf {
|
||||||
|
|
|
@ -9,7 +9,9 @@ import v.util
|
||||||
import v.pkgconfig
|
import v.pkgconfig
|
||||||
|
|
||||||
fn (mut c Checker) comptime_call(mut node ast.ComptimeCall) ast.Type {
|
fn (mut c Checker) comptime_call(mut node ast.ComptimeCall) ast.Type {
|
||||||
node.left_type = c.expr(node.left)
|
if node.left !is ast.EmptyExpr {
|
||||||
|
node.left_type = c.expr(node.left)
|
||||||
|
}
|
||||||
if node.method_name == 'compile_error' {
|
if node.method_name == 'compile_error' {
|
||||||
c.error(node.args_var, node.pos)
|
c.error(node.args_var, node.pos)
|
||||||
return ast.void_type
|
return ast.void_type
|
||||||
|
|
|
@ -165,9 +165,12 @@ fn (mut c Checker) for_stmt(mut node ast.ForStmt) {
|
||||||
c.in_for_count++
|
c.in_for_count++
|
||||||
prev_loop_label := c.loop_label
|
prev_loop_label := c.loop_label
|
||||||
c.expected_type = ast.bool_type
|
c.expected_type = ast.bool_type
|
||||||
typ := c.expr(node.cond)
|
if node.cond !is ast.EmptyExpr {
|
||||||
if !node.is_inf && typ.idx() != ast.bool_type_idx && !c.pref.translated && !c.file.is_translated {
|
typ := c.expr(node.cond)
|
||||||
c.error('non-bool used as for condition', node.pos)
|
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 mut node.cond is ast.InfixExpr {
|
||||||
if node.cond.op == .key_is {
|
if node.cond.op == .key_is {
|
||||||
|
|
|
@ -12,7 +12,14 @@ pub fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type {
|
||||||
mut left_type := c.expr(node.left)
|
mut left_type := c.expr(node.left)
|
||||||
node.left_type = left_type
|
node.left_type = left_type
|
||||||
c.expected_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)
|
mut right_type := c.expr(node.right)
|
||||||
|
if node.op == .key_is {
|
||||||
|
c.inside_x_is_type = false
|
||||||
|
}
|
||||||
node.right_type = right_type
|
node.right_type = right_type
|
||||||
if left_type.is_number() && !left_type.is_ptr()
|
if left_type.is_number() && !left_type.is_ptr()
|
||||||
&& right_type in [ast.int_literal_type, ast.float_literal_type] {
|
&& 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{}
|
return Result{}
|
||||||
}
|
}
|
||||||
content_type := vweb.mime_types[ext]
|
content_type := vweb.mime_types[ext]
|
||||||
if content_type.len == O {
|
if content_type.len == 0 {
|
||||||
eprintln('no MIME type found for extension $ext')
|
eprintln('no MIME type found for extension $ext')
|
||||||
ctx.server_error(500)
|
ctx.server_error(500)
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Reference in New Issue