diff --git a/examples/tetris/tetris.v b/examples/tetris/tetris.v index 40d5f08e52..a18ff06010 100644 --- a/examples/tetris/tetris.v +++ b/examples/tetris/tetris.v @@ -362,7 +362,7 @@ fn (mut g Game) draw_ui() { if g.state == .gameover { g.gg.draw_rect(0, win_height / 2 - text_size, win_width, 5 * text_size, ui_color) - g.ft.draw_text(1, win_height / 2 + 0 * text_size, 'Game Over', over_cfg) + g.gg.draw_text(1, win_height / 2 + 0 * text_size, 'Game Over', over_cfg) g.ft.draw_text(1, win_height / 2 + 2 * text_size, 'Space to restart', over_cfg) } else if g.state == .paused { g.gg.draw_rect(0, win_height / 2 - text_size, win_width, diff --git a/vlib/v/ast/ast.v b/vlib/v/ast/ast.v index 203a7c2acc..049f020537 100644 --- a/vlib/v/ast/ast.v +++ b/vlib/v/ast/ast.v @@ -287,14 +287,15 @@ pub struct Stmt { */ pub struct Var { pub: - name string - expr Expr - is_mut bool - is_arg bool // fn args should not be autofreed + name string + expr Expr + is_mut bool + is_arg bool // fn args should not be autofreed pub mut: - typ table.Type - pos token.Position - is_used bool + typ table.Type + pos token.Position + is_used bool + is_changed bool // to detect mutable vars that are never changed } pub struct GlobalDecl { diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 4a9cf8e48f..e4d46ff2c2 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -59,8 +59,23 @@ pub fn (mut c Checker) check(ast_file ast.File) { for stmt in ast_file.stmts { c.stmt(stmt) } + // Check scopes + // TODO + /* + for i, obj in c.file.global_scope.objects { + match obj { + ast.Var { + if it.is_mut && !it.is_changed { + c.warn('`$it.name` is declared as mutable, but it was never changed', it.pos) + } + } + else {} + } + } + */ } +// not used right now pub fn (mut c Checker) check2(ast_file ast.File) []errors.Error { c.file = ast_file for stmt in ast_file.stmts { @@ -583,7 +598,8 @@ fn (mut c Checker) fail_if_immutable(expr ast.Expr) { c.error('`$it.name` is immutable, declare it with `mut` to make it mutable', it.pos) } - } else if it.name in c.const_names { + v.is_changed = true + } else if it.name in c.const_names { c.error('cannot modify constant `$it.name`', it.pos) } } diff --git a/vlib/v/parser/parser.v b/vlib/v/parser/parser.v index e9d7b53267..81458ab0ca 100644 --- a/vlib/v/parser/parser.v +++ b/vlib/v/parser/parser.v @@ -12,9 +12,9 @@ import v.util import v.errors import os import runtime -//import sync import time +// import sync pub struct Parser { file_name string // "/home/user/hello.v" file_name_dir string // "/home/user" @@ -173,7 +173,6 @@ fn (mut q Queue) run() { } } */ - pub fn parse_files(paths []string, table &table.Table, pref &pref.Preferences, global_scope &ast.Scope) []ast.File { // println('nr_cpus= $nr_cpus') $if macos { @@ -234,6 +233,7 @@ pub fn (mut p Parser) open_scope() { } pub fn (mut p Parser) close_scope() { + // TODO move this to checker since is_changed is set there? if !p.pref.is_repl && !p.scanner.is_fmt { for _, obj in p.scope.objects { match obj { @@ -245,6 +245,12 @@ pub fn (mut p Parser) close_scope() { p.warn_with_pos('unused variable: `$it.name`', it.pos) } } + /* + if it.is_mut && !it.is_changed { + p.warn_with_pos('`$it.name` is declared as mutable, but it was never changed', + it.pos) + } + */ } else {} } @@ -1486,7 +1492,7 @@ fn (mut p Parser) type_decl() ast.TypeDecl { } else { table.Language.v } - p.table.register_type_symbol(table.TypeSymbol{ + p.table.register_type_symbol({ kind: .alias name: p.prepend_mod(name) parent_idx: pid