diff --git a/cmd/tools/vast/vast.v b/cmd/tools/vast/vast.v index 094f45f587..120af05ef0 100644 --- a/cmd/tools/vast/vast.v +++ b/cmd/tools/vast/vast.v @@ -385,8 +385,8 @@ fn (t Tree) objects(so map[string]ast.ScopeObject) &Node { } fn (t Tree) scope_object(node ast.ScopeObject) &Node { - mut obj := create_object() - match node { + obj := match node { + ast.EmptyScopeObject { create_object() } ast.ConstField { t.const_field(node) } ast.GlobalField { t.global_field(node) } ast.Var { t.var(node) } diff --git a/vlib/v/ast/ast.v b/vlib/v/ast/ast.v index 18ae4d85c4..61e115a898 100644 --- a/vlib/v/ast/ast.v +++ b/vlib/v/ast/ast.v @@ -117,7 +117,13 @@ pub type Stmt = AsmStmt | StructDecl | TypeDecl -pub type ScopeObject = AsmRegister | ConstField | GlobalField | Var +pub struct EmptyScopeObject { +pub mut: + name string + typ Type +} + +pub type ScopeObject = EmptyScopeObject | AsmRegister | ConstField | GlobalField | Var // TODO: replace Param pub type Node = CallArg @@ -209,6 +215,7 @@ pub: pub const empty_expr = Expr(EmptyExpr(0)) pub const empty_stmt = Stmt(EmptyStmt{}) pub const empty_node = Node(EmptyNode{}) +pub const empty_scope_object = ScopeObject(EmptyScopeObject{'empty_scope_object', 0}) pub const empty_comptime_const_value = ComptTimeConstValue(EmptyExpr(0)) // `{stmts}` or `unsafe {stmts}` @@ -1076,8 +1083,8 @@ pub: mut_pos token.Pos comptime bool pub mut: - scope &Scope = unsafe { nil } - obj ScopeObject + scope &Scope = unsafe { nil } + obj ScopeObject = empty_scope_object mod string name string full_name string @@ -1115,7 +1122,7 @@ pub fn (i &Ident) is_auto_heap() bool { pub fn (i &Ident) is_mut() bool { match i.obj { Var { return i.obj.is_mut } - ConstField { return false } + ConstField, EmptyScopeObject { return false } AsmRegister, GlobalField { return true } } } @@ -2403,7 +2410,7 @@ pub fn (node Node) pos() token.Pos { ConstField, GlobalField, Var { return node.pos } - AsmRegister { + EmptyScopeObject, AsmRegister { return token.Pos{ len: -1 line_nr: -1 @@ -2551,7 +2558,7 @@ pub fn (node Node) children() []Node { } else if node is ScopeObject { match node { GlobalField, ConstField, Var { children << node.expr } - AsmRegister {} + AsmRegister, EmptyScopeObject {} } } else { match node { diff --git a/vlib/v/ast/scope.v b/vlib/v/ast/scope.v index 03cf92b7c5..8cd33a0e62 100644 --- a/vlib/v/ast/scope.v +++ b/vlib/v/ast/scope.v @@ -111,8 +111,21 @@ pub fn (s &Scope) find_const(name string) ?&ConstField { } pub fn (s &Scope) known_var(name string) bool { - s.find_var(name) or { return false } - return true + if s == unsafe { nil } { + return false + } + for sc := unsafe { s }; true; sc = sc.parent { + if name in sc.objects { + obj := unsafe { sc.objects[name] or { empty_scope_object } } + if obj is Var { + return true + } + } + if sc.dont_lookup_parent() { + break + } + } + return false } pub fn (s &Scope) known_global(name string) bool { diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 0e12b5b8e4..794f042d07 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -4639,7 +4639,7 @@ fn (mut c Checker) find_obj_definition(obj ast.ScopeObject) !ast.Expr { // TODO: remove once we have better type inference mut name := '' match obj { - ast.Var, ast.ConstField, ast.GlobalField, ast.AsmRegister { name = obj.name } + ast.EmptyScopeObject, ast.Var, ast.ConstField, ast.GlobalField, ast.AsmRegister { name = obj.name } } mut expr := ast.empty_expr if obj is ast.Var { diff --git a/vlib/v/gen/native/gen.v b/vlib/v/gen/native/gen.v index ed1f1a4260..026622d5b1 100644 --- a/vlib/v/gen/native/gen.v +++ b/vlib/v/gen/native/gen.v @@ -906,6 +906,7 @@ fn (mut g Gen) is_fp_type(typ ast.Type) bool { fn (mut g Gen) get_sizeof_ident(ident ast.Ident) i32 { typ := match ident.obj { + ast.EmptyScopeObject { ident.obj.typ } ast.AsmRegister { ast.i64_type } ast.ConstField { ident.obj.typ } ast.GlobalField { ident.obj.typ }