checker: add error for `if c >= A && c <= Z {` in non generic functions
							parent
							
								
									701526e310
								
							
						
					
					
						commit
						726938ca57
					
				| 
						 | 
				
			
			@ -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 {
 | 
			
		||||
	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' {
 | 
			
		||||
		c.error(node.args_var, node.pos)
 | 
			
		||||
		return ast.void_type
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -165,9 +165,12 @@ 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
 | 
			
		||||
	typ := c.expr(node.cond)
 | 
			
		||||
	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 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 {
 | 
			
		||||
			c.error('non-bool used as for condition', node.pos)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if mut node.cond is ast.InfixExpr {
 | 
			
		||||
		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)
 | 
			
		||||
	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