diff --git a/src/codegen.pr b/src/codegen.pr index 8f490a35..69947291 100644 --- a/src/codegen.pr +++ b/src/codegen.pr @@ -12,7 +12,7 @@ import builtins def type_to_str(tpe: &typechecking::Type) -> Str { if not tpe { return "void" } if tpe.kind == typechecking::TypeKind::BOX { - tpe = tpe.weak + tpe = tpe.wk } var ret: StringBuffer = "" switch tpe.kind !int { diff --git a/src/compiler.pr b/src/compiler.pr index ba6f38c6..3fff99e0 100644 --- a/src/compiler.pr +++ b/src/compiler.pr @@ -466,7 +466,7 @@ def take_snapshot(function: &Function) { export type Function = struct { is_global: bool - module: weak_ref(toolchain::Module) + module: weak &toolchain::Module imported: bool dllimport: bool dllexport: bool @@ -518,9 +518,9 @@ export type Function = struct { // Closures is_closure: bool state: &typechecking::Type - scope: weak_ref(scope::Scope) - inner_scope: weak_ref(scope::Scope) - captures: &Vector(weak_ref(scope::Value)) + scope: weak &scope::Scope + inner_scope: weak &scope::Scope + captures: &Vector(weak &scope::Value) is_compiled: bool is_typechecked: bool @@ -567,7 +567,7 @@ type LoopState = struct { } export type State = struct { - module: weak_ref(toolchain::Module) + module: weak &toolchain::Module global_counter: int meta_counter: int local_counter: int @@ -584,7 +584,7 @@ export type State = struct { // Used by eval globals: &SMap(*) mem: &arena::Arena - scope: weak_ref(scope::Scope) + scope: weak &scope::Scope // Destructor function finalizer: &Function consteval: bool @@ -1111,7 +1111,7 @@ def import_structure(tpe: &typechecking::Type, module: &toolchain::Module) { export def import_structures(tpe: &typechecking::Type, module: &toolchain::Module) { if not tpe { return } if tpe.kind == typechecking::TypeKind::BOX { - tpe = tpe.weak + tpe = tpe.wk } switch tpe.kind !int { case typechecking::TypeKind::STRUCT..=typechecking::TypeKind::UNION @@ -3079,7 +3079,7 @@ def walk_Call(node: &parser::Node, state: &State) -> Value { insert_copy_constructor(ret, expr, loc, state) expr = state.load(expr.tpe, ret, loc) } - // TODO Does this need to do something for weak references? + // TODO Does this need to do something for wk references? if typechecking::is_ref(last_np.tpe) and not typechecking::is_ref(n.tpe) { create_type(reference(n.tpe), state.module) // We need to increase the ref count and add the destructor call @@ -4046,7 +4046,7 @@ def walk_MemberAccess_struct(node: &parser::Node, tpe: &typechecking::Type, memb var member_type = member.tpe if member.tpe.kind == typechecking::TypeKind::BOX { - member_type = member.tpe.weak + member_type = member.tpe.wk } if tpe.kind == typechecking::TypeKind::UNION { @@ -6654,7 +6654,7 @@ def di_type(tpe: &typechecking::Type, state: &State) -> &Value { (@state).ditypes(tpe) = ditpep if tpe.kind == typechecking::TypeKind::BOX { - tpe = tpe.weak + tpe = tpe.wk } switch tpe.kind !int { // TODO compare with char for special casing @@ -8958,7 +8958,7 @@ def do_create_type(tpe: &typechecking::Type, svalue: &scope::Value, module: &too if toolchain::no_stdlib { return NO_VALUE } if tpe.kind == typechecking::TypeKind::BOX { - tpe = tpe.weak + tpe = tpe.wk } let generic = typechecking::get_generic(tpe) @@ -9181,7 +9181,7 @@ def do_create_type(tpe: &typechecking::Type, svalue: &scope::Value, module: &too // Map of ToResolve let types_to_resolve = map::make(ToResolve) type ToResolve = struct { - module: weak_ref(toolchain::Module) + module: weak &toolchain::Module tpe: &typechecking::Type } @@ -9204,13 +9204,13 @@ export def resolve_types { type TypeEntry = struct { tpe: &typechecking::Type value: &scope::Value - module: weak_ref(toolchain::Module) + module: weak &toolchain::Module } export def create_type(tpe: &typechecking::Type, module: &toolchain::Module, cache: &Vector(TypeEntry)) -> &Value { if not tpe { return null } if tpe.kind == typechecking::TypeKind::BOX { - tpe = tpe.weak + tpe = tpe.wk } if tpe.tc_incomplete { return null } let generic = typechecking::get_generic(tpe) diff --git a/src/consteval.pr b/src/consteval.pr index f18c81c8..dbb86599 100644 --- a/src/consteval.pr +++ b/src/consteval.pr @@ -414,7 +414,7 @@ export def walk_Def(node: &parser::Node, state: &typechecking::State) { is_closure = node.parent.kind != parser::NodeKind::PROGRAM, scope = state.scope, inner_scope = node.inner_scope, - captures = vector::make(type weak_ref(scope::Value)), + captures = vector::make(type weak &scope::Value), dllimport = dllimport, dllexport = dllexport or test, test = test, diff --git a/src/debug.pr b/src/debug.pr index 0a2cbad2..7b316179 100644 --- a/src/debug.pr +++ b/src/debug.pr @@ -835,7 +835,7 @@ export def type_to_str(tpe: &typechecking::Type, full_name: bool = false) -> Str if tpe.tc_tpe { return tc_args_to_string(tpe, full_name) } switch tpe.kind !int { case typechecking::TypeKind::BOX - return "Box<" + type_to_str(tpe.weak, full_name) + ">" + return "Box<" + type_to_str(tpe.wk, full_name) + ">" case typechecking::TypeKind::VOID return "void" case typechecking::TypeKind::BOOL diff --git a/src/lexer.pr b/src/lexer.pr index c090f4a3..bfeb07e2 100644 --- a/src/lexer.pr +++ b/src/lexer.pr @@ -99,8 +99,8 @@ export type TokenType = enum { K_ASSERT K_TYPE_OF K_UNDEF - K_WEAK_REF K_REF + K_WEAK INTEGER FLOAT STRING @@ -224,7 +224,7 @@ let KEYWORDS = [ [token_type = TokenType::K_DEFINED, str = "defined"] !Keyword, [token_type = TokenType::K_DEFER, str = "defer"] !Keyword, [token_type = TokenType::K_TYPE_OF, str = "type_of"] !Keyword, - [token_type = TokenType::K_WEAK_REF, str = "weak_ref"] !Keyword, + [token_type = TokenType::K_WEAK, str = "weak"] !Keyword, [token_type = TokenType::K_YIELD, str = "yield"] !Keyword, [token_type = TokenType::K_IMPLICIT, str = "implicit"] !Keyword, [token_type = TokenType::K_REF, str = "ref"] !Keyword diff --git a/src/parser.pr b/src/parser.pr index affdab97..e46ac1aa 100644 --- a/src/parser.pr +++ b/src/parser.pr @@ -465,7 +465,7 @@ export type Node = struct { // For things like if statements or functions inner_scope: &scope::Scope value: NodeValue - parent: weak_ref(Node) + parent: weak &Node // Set to prevent destructors being called on uninitalized values is_initializer: bool @@ -475,7 +475,7 @@ export type Node = struct { body: &Vector(&Node) // This is used by assignment to track let kw: VarDecl - module: weak_ref(toolchain::Module) + module: weak &toolchain::Module is_recursive_type: bool // Need to keep copied type nodes in the tree @@ -1856,43 +1856,17 @@ def expect_array_or_tuple(parse_state: &ParseState) -> &Node { } def expect_weak_ref(parse_state: &ParseState, inline_types: bool) -> &Node { - var tok = expect(parse_state, lexer::TokenType::K_WEAK_REF, "Expected weak_ref") + var tok = expect(parse_state, lexer::TokenType::K_WEAK, "Expected weak") let line = tok.line let column = tok.column - - var tpe: &Node = null - var kw = VarDecl::VAR - tok = peek(parse_state) - if tok.tpe == lexer::TokenType::O_PAREN { - pop(parse_state) - skip_newline(parse_state) - tok = peek(parse_state) - if tok.tpe == lexer::TokenType::K_VAR { - pop(parse_state) - skip_newline(parse_state) - } else if tok.tpe == lexer::TokenType::K_LET { - pop(parse_state) - kw = VarDecl::LET - skip_newline(parse_state) - } - - var tokens = parse_state.tokens - tpe = parse_type(parse_state, inline_types) - if not tpe { - parse_state.tokens = tokens - } - - skip_newline(parse_state) - expect(parse_state, lexer::TokenType::C_PAREN, "Expected ')'") - } + let tpe = expect_type(parse_state) var node = make_node(NodeKind::WEAK_REF_T, line, column, parse_state) node.value.t_parr = [ - kw = kw, tpe = tpe ] !NodePtrArrayT - node._hash = combine_hashes(node.kind !uint64, kw !uint64, hash(tpe)) + node._hash = combine_hashes(node.kind !uint64, hash(tpe)) return node } @@ -2414,7 +2388,7 @@ def parse_type2(parse_state: &ParseState, inline_types: bool) -> &Node { tok.tpe == lexer::TokenType::OP_BAND { back(parse_state) return expect_ptr_ref(parse_state, tok.tpe == lexer::TokenType::OP_BAND, inline_types) - } else if tok.tpe == lexer::TokenType::K_WEAK_REF { + } else if tok.tpe == lexer::TokenType::K_WEAK { back(parse_state) return expect_weak_ref(parse_state, inline_types) } else if tok.tpe == lexer::TokenType::DOUBLE_COLON or diff --git a/src/scope.pr b/src/scope.pr index 7364e0ee..110b8157 100644 --- a/src/scope.pr +++ b/src/scope.pr @@ -16,11 +16,11 @@ export type Ident = struct { name: Str signature: Str _hash: uint64 - module: weak_ref(toolchain::Module) + module: weak &toolchain::Module } export type ImportedModule = struct { - module: weak_ref(toolchain::Module) + module: weak &toolchain::Module alias: &parser::Node } @@ -72,7 +72,7 @@ export def find(ident: Ident) -> &Value { export type Value = struct { // This is needed to store the location - name_node: weak_ref(parser::Node) + name_node: weak &parser::Node share: parser::ShareMarker modifier: parser::VarDecl // Name used by the source code @@ -85,7 +85,7 @@ export type Value = struct { tpe: &typechecking::Type value: &compiler::Value _scope: &Scope - _module: weak_ref(Scope) // This is needed for modules referencing each other + _module: weak &Scope // This is needed for modules referencing each other // In case multiple values share one name (overloaded functions) next: &Value phase: Phase @@ -97,7 +97,7 @@ export type Value = struct { dllimport: bool dllexport: bool // Definition of the value - node: weak_ref(parser::Node) + node: weak &parser::Node state: &typechecking::State // For imported scopes, this checks if a value is exported before accessing it // Also used by serialize to signal that a function is imported (ffi) @@ -122,7 +122,7 @@ export type Value = struct { references: &Vector(parser::SourceLoc) // Don't serialize these is_generated: bool - module: weak_ref(toolchain::Module) + module: weak &toolchain::Module } export def assembly_name(value: &Value, state: &compiler::State) -> Str { @@ -198,16 +198,16 @@ export def find_references_to(value: &Value) -> &Vector(parser::SourceLoc) { } export type ReExport = struct { - module: weak_ref(toolchain::Module) + module: weak &toolchain::Module pattern: &parser::Node } export type Scope = struct { - module: weak_ref(toolchain::Module) + module: weak &toolchain::Module is_function: bool // Counter for local scopes (shadowing) scope_count: int - parent: weak_ref(Scope) + parent: weak &Scope fields: &SMap(&Value) implicits: &Vector(&Value) // This is a list of imported scopes, @@ -938,7 +938,7 @@ export def generate_function(scope: &Scope, node: &parser::Node, parameter_t: &V for var i in 0..found_member.return_t.length { var tpe = found_member.return_t(i) if tpe.kind == typechecking::TypeKind::BOX { - tpe = tpe.weak + tpe = tpe.wk } return_t.push(typechecking::copy(tpe)) } diff --git a/src/serialize.pr b/src/serialize.pr index b3f797cd..6817cdf9 100644 --- a/src/serialize.pr +++ b/src/serialize.pr @@ -14,7 +14,7 @@ import util import builtins type Serialize = struct { - module: weak_ref(toolchain::Module) + module: weak &toolchain::Module types: &Map(&typechecking::Type, int64) dependencies: &Set(scope::Ident) } @@ -25,7 +25,7 @@ def add_type(tpe: &typechecking::Type, state: &Serialize) -> int64 { if not tpe { return -1 } if tpe.kind == typechecking::TypeKind::BOX { - tpe = tpe.weak + tpe = tpe.wk assert tpe.kind != typechecking::TypeKind::BOX } @@ -139,7 +139,7 @@ def serialize_type(fp: File, tpe: &typechecking::Type, state: &Serialize) { return } if tpe.kind == typechecking::TypeKind::BOX { - tpe = tpe.weak + tpe = tpe.wk } assert tpe.kind != typechecking::TypeKind::BOX @@ -1091,7 +1091,7 @@ type TypeEntry = struct { } export type Deserialize = struct { - module: weak_ref(toolchain::Module) + module: weak &toolchain::Module types: &Vector(&typechecking::Type) nodes: &Vector(&parser::Node) // Strong references to nodes scopes: &Vector(&scope::Scope) // Strong references to enum scopes diff --git a/src/toolchain.pr b/src/toolchain.pr index e0ba116e..356bf4c9 100644 --- a/src/toolchain.pr +++ b/src/toolchain.pr @@ -216,7 +216,7 @@ export type Module = struct { difile: &compiler::Value stage: Stage imports: &Set(Str) - dependants: &Set(weak_ref(Module)) + dependants: &Set(weak &Module) // List of Type // This is a list of functions that are generated for dynamic dispatch dyn_dispatch_consteval: &Vector(&typechecking::Type) @@ -225,7 +225,7 @@ export type Module = struct { // This is needed to generate functions from create_destructor compiler_state: &compiler::State state: &typechecking::State - unresolved: &Map(scope::Ident, weak_ref(scope::Value)) + unresolved: &Map(scope::Ident, weak &scope::Value) // Incremental compilation // This is set to true if the source file is newer than the cache or // any of the dependencies changed @@ -304,10 +304,10 @@ export def make_module( code = compiler::make_block(), imported = set::make(), imports = set::make(Str), - dependants = set::make(type weak_ref(Module)), + dependants = set::make(type weak &Module), dyn_dispatch_consteval = vector::make(type &typechecking::Type), dyn_dispatch = vector::make(type &typechecking::Type), - unresolved = map::make(scope::Ident, type weak_ref(scope::Value)), + unresolved = map::make(scope::Ident, type weak &scope::Value), inlay_hints = vector::make(type &parser::Node), closures = vector::make(type &scope::Value), is_dirty = no_incremental, diff --git a/src/typechecking.pr b/src/typechecking.pr index 34269e36..b9cdf251 100644 --- a/src/typechecking.pr +++ b/src/typechecking.pr @@ -60,9 +60,9 @@ export type TypeKind = enum { // Tagged union types, very similar to VARIANT but the equality relation is different // This is actually called variant in runtime TUNION - // References to structs are using a weak reference, ie. Type::weak instead of Type::_tpe + // References to structs are using a wk reference, ie. Type::wk instead of Type::_tpe // This is because references to structs can cause cycles - // TODO I think we don't really need this because we can just use weak directly + // TODO I think we don't really need this because we can just use wk directly BOX VOID TO_INFER // Placeholder type for inference @@ -76,7 +76,7 @@ export type TypeMember = struct { export type StructMember = struct { // Source line line: int - node: weak_ref(parser::Node) + node: weak &parser::Node name: Str tpe: &Type // index into the field_types vector @@ -100,7 +100,7 @@ export type StructuralTypeMember = struct { } export type TypeRef = struct { - module: weak_ref(toolchain::Module) + module: weak &toolchain::Module name: Str } @@ -121,10 +121,10 @@ export type Type = struct { kind: TypeKind // Source line line: int - module: weak_ref(toolchain::Module) + module: weak &toolchain::Module // Module that this type was defined in - _defmodule: weak_ref(toolchain::Module) - context: weak_ref(toolchain::Module) + _defmodule: weak &toolchain::Module + context: weak &toolchain::Module state: &State // Name of the type as used by the source code // Might be the name of a typedef @@ -142,7 +142,7 @@ export type Type = struct { // This is also used for type arguments to specify the actual type // And tagged unions carry the underlying union type _tpe: &Type - weak: weak_ref(Type) + wk: weak &Type packed: bool // Fields for struct, array of StructMember fields: &[StructMember] @@ -155,18 +155,18 @@ export type Type = struct { // Vector of NamedParameter parameter_t: &Vector(NamedParameter) // Enum scope - scope: weak_ref(scope::Scope) + scope: weak &scope::Scope // Structural types // Vector of StructuralTypeMember members: &Vector(StructuralTypeMember) share: parser::ShareMarker // TODO Types should not have a share, this needs to be on the value instead (and only there) - node: weak_ref(parser::Node) + node: weak &parser::Node // Type constructors save a template of a type - tc_node: weak_ref(parser::Node) + tc_node: weak &parser::Node // Cache of specialized type constructor cache: &Map(TypeRef, &Type) // Type constructor instances have a type and arguments - tc_tpe: weak_ref(Type) + tc_tpe: weak &Type // Vector of Type, also used by GENERIC tc_args: &Vector(&Type) // True if some parameters weren't set yet @@ -175,10 +175,10 @@ export type Type = struct { // This is used by variant, tagged union and interface impl variants: &Set(&Type) _hash: uint64 - svalue: weak_ref(scope::Value) + svalue: weak &scope::Value // This is used by deserialization to check if a type is in the - // type cache, so that structs can keep a weak reference to the type + // type cache, so that structs can keep a wk reference to the type is_in_type_cache: bool // Set on type arguments is_type_argument: bool @@ -482,7 +482,7 @@ export def has_copy_constructor(tpe: &Type, lookup: bool = true) -> bool { return res } -export def defmodule(tpe: &Type) -> weak_ref(toolchain::Module) { +export def defmodule(tpe: &Type) -> weak &toolchain::Module { if not tpe { return null } if tpe._defmodule { return tpe._defmodule } return tpe.module @@ -491,7 +491,7 @@ export def defmodule(tpe: &Type) -> weak_ref(toolchain::Module) { export def tpe(tpe: &Type) -> &Type { if not tpe { return null } if tpe._tpe and tpe._tpe.kind == TypeKind::BOX { - return tpe._tpe.weak + return tpe._tpe.wk } return tpe._tpe } @@ -505,7 +505,7 @@ export def get_module(tpe: &Type) -> &toolchain::Module { export def box(tpe: &Type) -> &Type { if not tpe { return null } let box = make_type_raw(TypeKind::BOX) - box.weak = tpe + box.wk = tpe return box } @@ -514,24 +514,24 @@ export type NamedParameter = struct { name: Str _tpe: &Type varargs: bool - node: weak_ref(parser::Node) + node: weak &parser::Node value: &compiler::Value kw: parser::VarDecl - type_node: weak_ref(parser::Node) + type_node: weak &parser::Node } export def tpe(np: NamedParameter) -> &Type { if not np._tpe { return null } if np._tpe.kind == TypeKind::BOX { - return np._tpe.weak + return np._tpe.wk } return np._tpe } export type State = struct { - module: weak_ref(toolchain::Module) + module: weak &toolchain::Module counter: int - scope: weak_ref(scope::Scope) + scope: weak &scope::Scope // Vector of Type function_stack: &Vector(&compiler::Function) in_defer: bool @@ -673,7 +673,7 @@ export def is_box(tpe: &Type) -> bool { export def unbox(tpe: &Type) -> &Type { if not tpe { return null } if tpe.kind == TypeKind::BOX { - return tpe.weak + return tpe.wk } return tpe } @@ -1040,7 +1040,7 @@ export type TypeEntry = struct { export type TypeEntryMember = struct { function: &Type exported: bool - module: weak_ref(toolchain::Module) + module: weak &toolchain::Module } export def create_type_entry(tpe: &Type) -> &TypeEntry { @@ -1127,7 +1127,7 @@ export def copy(a: &Type) -> &Type { a.kind == TypeKind::TYPE_DEF or a.kind == TypeKind::TYPE { if a._tpe and a._tpe.kind == TypeKind::BOX { - t._tpe = copy(a._tpe.weak) // Unbox for copy + t._tpe = copy(a._tpe.wk) // Unbox for copy } else { t._tpe = copy(a._tpe) } @@ -1152,10 +1152,10 @@ export def equals(a: &Type, b: &Type) -> bool { } if not a or not b { return false } if a.kind == TypeKind::BOX { - a = a.weak + a = a.wk } if b.kind == TypeKind::BOX { - b = b.weak + b = b.wk } if a.kind != TypeKind::TYPE and a._hash and b._hash { @@ -1341,7 +1341,7 @@ def has_function(entry: &TypeEntry, intf: &Type, mb: StructuralTypeMember, modul let ta = return_t(k) var tb = mb.return_t(k) if tb.kind == TypeKind::BOX { - tb = tb.weak + tb = tb.wk } if not equals(ta, tb) { mismatch = true @@ -1395,9 +1395,9 @@ export def implements(a: &Type, b: &Type, module: &toolchain::Module, visited: & for var k in 0..vector::length(ma.return_t) { var ta = ma.return_t(k) - if ta.kind == TypeKind::BOX { ta = ta.weak } + if ta.kind == TypeKind::BOX { ta = ta.wk } var tb = mb.return_t(k) - if tb.kind == TypeKind::BOX { ta = tb.weak } + if tb.kind == TypeKind::BOX { ta = tb.wk } if not equals(ta, tb) { mismatch = true break @@ -1548,10 +1548,10 @@ const IMPLICIT = 15 export def convert_type_score(a: &Type, b: &Type, module: &toolchain::Module, is_type: bool = false, impl: bool = true) -> int { if not a or not b { return 0 } if a.kind == TypeKind::BOX { - a = a.weak + a = a.wk } if b.kind == TypeKind::BOX { - b = b.weak + b = b.wk } if equals(a, b) { @@ -2550,6 +2550,12 @@ def lookup_field_type(node: &parser::Node, state: &State, current_type: &Type, c node.kind == parser::NodeKind::WEAK_REF_T or node.kind == parser::NodeKind::FUNCTION_T or node.kind == parser::NodeKind::CLOSURE_T { + + let prev_node = node + if node.kind == parser::NodeKind::WEAK_REF_T { + // Unwrap weak ref + node = node.value.t_parr.tpe + } if node.kind == parser::NodeKind::FUNCTION_T { let box = box(type_lookup(node, state, current_type, false, cache)) @@ -2583,18 +2589,24 @@ def lookup_field_type(node: &parser::Node, state: &State, current_type: &Type, c } } - if node.kind == parser::NodeKind::PTR_T { + if prev_node.kind == parser::NodeKind::PTR_T { stub = pointer(stub, node.value.t_parr.kw) - } else if node.kind == parser::NodeKind::REF_T { + } else if prev_node.kind == parser::NodeKind::REF_T { stub = reference(stub, node.value.t_parr.kw) - } else if node.kind == parser::NodeKind::ARRAY_T { + } else if prev_node.kind == parser::NodeKind::ARRAY_T { stub = array(stub, node.value.t_parr.kw) - } else if node.kind == parser::NodeKind::WEAK_REF_T { + } + + if prev_node.kind == parser::NodeKind::WEAK_REF_T { stub = weak_reference(stub, node.value.t_parr.kw) + stub.module = state.module + stub.node = node + prev_node.tpe = stub + } else { + stub.module = state.module + stub.node = node + node.tpe = stub } - stub.module = state.module - stub.node = node - node.tpe = stub return stub } else { @@ -2672,7 +2684,10 @@ export def do_type_lookup(node: &parser::Node, state: &State, current_type: &Typ node.scope = state.scope if node.value.t_parr.tpe { node.value.t_parr.tpe.parent = node } var tpe = type_lookup(node.value.t_parr.tpe, state, current_type, lookup_default, cache) - tpe = weak_reference(tpe, node.value.t_parr.kw) + if not tpe or tpe.kind != TypeKind::REFERENCE { + errors::errorn(node, "Weak reference must point at a reference!") + } + tpe = weak_reference(tpe.tpe, tpe.kw) return tpe } else if node.kind == parser::NodeKind::STRUCT_T or node.kind == parser::NodeKind::UNION_T { @@ -4361,7 +4376,7 @@ export def walk_Lambda(node: &parser::Node, state: &State) { is_closure = true, scope = state.scope, inner_scope = inner_scope, - captures = vector::make(type weak_ref(scope::Value)) + captures = vector::make(type weak &scope::Value) ] !&compiler::Function node.value.lambda.function = function @@ -4583,7 +4598,7 @@ export def walk_Def(node: &parser::Node, state: &State, polymorph: bool = false) is_closure = node.parent.kind != parser::NodeKind::PROGRAM, scope = state.scope, inner_scope = inner_scope, - captures = vector::make(type weak_ref(scope::Value)), + captures = vector::make(type weak &scope::Value), dllimport = dllimport, dllexport = dllexport, test = test, @@ -5097,7 +5112,7 @@ export def walk_Call(node: &parser::Node, dry_run: bool, state: &State) -> bool var tpe = (@left).tpe if tpe and tpe.kind == typechecking::TypeKind::BOX { - tpe = tpe.weak + tpe = tpe.wk } var arguments = vector::make(NamedParameter) @@ -5644,12 +5659,16 @@ export def lookup_struct_member(member: StructMember, resolved: &SSet = null) { if (is_pointer(tpe) or tpe.kind == TypeKind::REFERENCE or - tpe.kind == TypeKind::WEAK_REF or tpe.kind == TypeKind::ARRAY) { if tpe._tpe and tpe._tpe.kind == TypeKind::STUB and tpe._tpe.state { tpe._tpe = box(type_lookup(tpe._tpe.node, tpe._tpe.state)) } tpe._hash = 0 + } else if tpe.kind == TypeKind::WEAK_REF { + if tpe._tpe and tpe._tpe.kind == TypeKind::STUB and tpe._tpe.state { + tpe._tpe = box(type_lookup(tpe.node.value.t_parr.tpe, tpe._tpe.state)) + } + tpe._hash = 0 } else if tpe.kind == typechecking::TypeKind::STRUCT { for var i in 0..tpe.fields.size { let field = tpe.fields(i) @@ -5747,7 +5766,7 @@ def walk_MemberAccess_aggregate(node: &parser::Node, ucs: bool, state: &State) - return false } if rtpe.kind == TypeKind::BOX { - rtpe = rtpe.weak + rtpe = rtpe.wk } node.tpe = rtpe } else if (@tpe).kind == TypeKind::ARRAY or (@tpe).kind == TypeKind::STATIC_ARRAY { diff --git a/std/map.pr b/std/map.pr index 46d50303..1850b399 100644 --- a/std/map.pr +++ b/std/map.pr @@ -9,15 +9,15 @@ export type Entry(type K, type V) = struct { value: V next: &Entry(K, V) // We maintain a linked list for ordering - l_prev: weak_ref(Entry(K, V)) - l_next: weak_ref(Entry(K, V)) + l_prev: weak &Entry(K, V) + l_next: weak &Entry(K, V) } export type Map(type K, type V) = struct { size: size_t entries: [&Entry(K, V)] - tail: weak_ref(Entry(K, V)) - head: weak_ref(Entry(K, V)) + tail: weak &Entry(K, V) + head: weak &Entry(K, V) } export type SMap(type V) = Map(Str, V) diff --git a/test/test_parser.pr b/test/test_parser.pr index ec261437..d908b82f 100644 --- a/test/test_parser.pr +++ b/test/test_parser.pr @@ -1285,7 +1285,7 @@ def #test test_pointer_types { "tpe": null }""")) - assert parse("(type weak_ref(T))") == program(json::parse("""{ + assert parse("(type weak &T)") == program(json::parse("""{ "kind": "WeakRefT", "kw": "VAR", "tpe": { @@ -1298,7 +1298,7 @@ def #test test_pointer_types { } }""")) - assert parse("(type weak_ref(var T))") == program(json::parse("""{ + assert parse("(type weak &var T)") == program(json::parse("""{ "kind": "WeakRefT", "kw": "VAR", "tpe": { @@ -1311,7 +1311,7 @@ def #test test_pointer_types { } }""")) - assert parse("(type weak_ref(let *T))") == program(json::parse("""{ + assert parse("(type weak &let *T)") == program(json::parse("""{ "kind": "WeakRefT", "kw": "LET", "tpe": { @@ -1328,19 +1328,19 @@ def #test test_pointer_types { } }""")) - assert parse("(type weak_ref())") == program(json::parse(""" { + assert parse("(type weak &)") == program(json::parse(""" { "kind": "WeakRefT", "kw": "VAR", "tpe": null }""")) - assert parse("(type weak_ref(let))") == program(json::parse("""{ + assert parse("(type weak &let)") == program(json::parse("""{ "kind": "WeakRefT", "kw": "LET", "tpe": null }""")) - assert parse("(type weak_ref(var))") == program(json::parse(""" { + assert parse("(type weak &var)") == program(json::parse(""" { "kind": "WeakRefT", "kw": "VAR", "tpe": null