diff options
| author | Martin Wickham <spexguy070@gmail.com> | 2021-09-30 13:34:12 -0500 |
|---|---|---|
| committer | Martin Wickham <spexguy070@gmail.com> | 2021-10-02 15:21:48 -0500 |
| commit | 269e54877051791790f5dffc4d4f1476834e4e43 (patch) | |
| tree | f1a050defea8bff3d8f39934fdca4111afb1af0f /src | |
| parent | 4916e26be434309209585a7c8a7918ed58c79466 (diff) | |
| download | zig-269e54877051791790f5dffc4d4f1476834e4e43.tar.gz zig-269e54877051791790f5dffc4d4f1476834e4e43.zip | |
Fix namespace references for deeply nested structs
Diffstat (limited to 'src')
| -rw-r--r-- | src/Module.zig | 19 | ||||
| -rw-r--r-- | src/Sema.zig | 41 |
2 files changed, 21 insertions, 39 deletions
diff --git a/src/Module.zig b/src/Module.zig index 6c790d3804..c398081bc3 100644 --- a/src/Module.zig +++ b/src/Module.zig @@ -1107,7 +1107,7 @@ pub const Scope = struct { /// Asserts the scope has a parent which is a Namespace and returns it. pub fn namespace(scope: *Scope) *Namespace { switch (scope.tag) { - .block => return scope.cast(Block).?.sema.owner_decl.namespace, + .block => return scope.cast(Block).?.src_decl.namespace, .file => return scope.cast(File).?.root_decl.?.namespace, .namespace => return scope.cast(Namespace).?, } @@ -3244,11 +3244,11 @@ pub fn semaFile(mod: *Module, file: *Scope.File) SemaError!void { .file_scope = file, }, }; - const new_decl = try mod.allocateNewDecl(&struct_obj.namespace, 0, null); + const decl_name = try file.fullyQualifiedNameZ(gpa); + const new_decl = try mod.allocateNewDecl(decl_name, &struct_obj.namespace, 0, null); file.root_decl = new_decl; struct_obj.owner_decl = new_decl; new_decl.src_line = 0; - new_decl.name = try file.fullyQualifiedNameZ(gpa); new_decl.is_pub = true; new_decl.is_exported = false; new_decl.has_align = false; @@ -3276,7 +3276,6 @@ pub fn semaFile(mod: *Module, file: *Scope.File) SemaError!void { .perm_arena = &new_decl_arena.allocator, .code = file.zir, .owner_decl = new_decl, - .namespace = &struct_obj.namespace, .func = null, .fn_ret_ty = Type.initTag(.void), .owner_func = null, @@ -3342,7 +3341,6 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool { .perm_arena = &decl_arena.allocator, .code = zir, .owner_decl = decl, - .namespace = decl.namespace, .func = null, .fn_ret_ty = Type.initTag(.void), .owner_func = null, @@ -3818,13 +3816,12 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) SemaError!voi // We create a Decl for it regardless of analysis status. const gop = try namespace.decls.getOrPut(gpa, decl_name); if (!gop.found_existing) { - const new_decl = try mod.allocateNewDecl(namespace, decl_node, iter.parent_decl.src_scope); + const new_decl = try mod.allocateNewDecl(decl_name, namespace, decl_node, iter.parent_decl.src_scope); if (is_usingnamespace) { namespace.usingnamespace_set.putAssumeCapacity(new_decl, is_pub); } log.debug("scan new {*} ({s}) into {*}", .{ new_decl, decl_name, namespace }); new_decl.src_line = line; - new_decl.name = decl_name; gop.value_ptr.* = new_decl; // Exported decls, comptime decls, usingnamespace decls, and // test decls if in test mode, get analyzed. @@ -4089,7 +4086,6 @@ pub fn analyzeFnBody(mod: *Module, decl: *Decl, func: *Fn, arena: *Allocator) Se .perm_arena = &decl_arena.allocator, .code = decl.namespace.file_scope.zir, .owner_decl = decl, - .namespace = decl.namespace, .func = func, .fn_ret_ty = func.owner_decl.ty.fnReturnType(), .owner_func = func, @@ -4226,7 +4222,7 @@ fn markOutdatedDecl(mod: *Module, decl: *Decl) !void { decl.analysis = .outdated; } -pub fn allocateNewDecl(mod: *Module, namespace: *Scope.Namespace, src_node: Ast.Node.Index, src_scope: ?*CaptureScope) !*Decl { +pub fn allocateNewDecl(mod: *Module, name: [:0]const u8, namespace: *Scope.Namespace, src_node: Ast.Node.Index, src_scope: ?*CaptureScope) !*Decl { // If we have emit-h then we must allocate a bigger structure to store the emit-h state. const new_decl: *Decl = if (mod.emit_h != null) blk: { const parent_struct = try mod.gpa.create(DeclPlusEmitH); @@ -4238,7 +4234,7 @@ pub fn allocateNewDecl(mod: *Module, namespace: *Scope.Namespace, src_node: Ast. } else try mod.gpa.create(Decl); new_decl.* = .{ - .name = "", + .name = name, .namespace = namespace, .src_node = src_node, .src_line = undefined, @@ -4414,9 +4410,8 @@ pub fn createAnonymousDeclFromDeclNamed( const namespace = src_decl.namespace; try namespace.anon_decls.ensureUnusedCapacity(mod.gpa, 1); - const new_decl = try mod.allocateNewDecl(namespace, src_decl.src_node, src_scope); + const new_decl = try mod.allocateNewDecl(name, namespace, src_decl.src_node, src_scope); - new_decl.name = name; new_decl.src_line = src_decl.src_line; new_decl.ty = typed_value.ty; new_decl.val = typed_value.val; diff --git a/src/Sema.zig b/src/Sema.zig index 8842a55dcc..218f4258b8 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -24,8 +24,6 @@ inst_map: InstMap = .{}, /// and `src_decl` of `Scope.Block` is the `Decl` of the callee. /// This `Decl` owns the arena memory of this `Sema`. owner_decl: *Decl, -/// How to look up decl names. -namespace: *Scope.Namespace, /// For an inline or comptime function call, this will be the root parent function /// which contains the callsite. Corresponds to `owner_decl`. owner_func: ?*Module.Fn, @@ -1048,6 +1046,8 @@ pub fn analyzeStructDecl( } else 0; _ = try sema.mod.scanNamespace(&struct_obj.namespace, extra_index, decls_len, new_decl); + + new_decl.namespace = &struct_obj.namespace; } fn zirStructDecl( @@ -1084,7 +1084,7 @@ fn zirStructDecl( .status = .none, .known_has_bits = undefined, .namespace = .{ - .parent = sema.owner_decl.namespace, + .parent = block.src_decl.namespace, .ty = struct_ty, .file_scope = block.getFileScope(), }, @@ -1194,7 +1194,7 @@ fn zirEnumDecl( .values = .{}, .node_offset = src.node_offset, .namespace = .{ - .parent = sema.owner_decl.namespace, + .parent = block.src_decl.namespace, .ty = enum_ty, .file_scope = block.getFileScope(), }, @@ -1205,6 +1205,8 @@ fn zirEnumDecl( extra_index = try mod.scanNamespace(&enum_obj.namespace, extra_index, decls_len, new_decl); + new_decl.namespace = &enum_obj.namespace; + const body = sema.code.extra[extra_index..][0..body_len]; if (fields_len == 0) { assert(body.len == 0); @@ -1227,10 +1229,6 @@ fn zirEnumDecl( sema.owner_decl = new_decl; defer sema.owner_decl = prev_owner_decl; - const prev_namespace = sema.namespace; - sema.namespace = &enum_obj.namespace; - defer sema.namespace = prev_namespace; - const prev_owner_func = sema.owner_func; sema.owner_func = null; defer sema.owner_func = prev_owner_func; @@ -1385,7 +1383,7 @@ fn zirUnionDecl( .layout = small.layout, .status = .none, .namespace = .{ - .parent = sema.owner_decl.namespace, + .parent = block.src_decl.namespace, .ty = union_ty, .file_scope = block.getFileScope(), }, @@ -1396,6 +1394,8 @@ fn zirUnionDecl( _ = try sema.mod.scanNamespace(&union_obj.namespace, extra_index, decls_len, new_decl); + new_decl.namespace = &union_obj.namespace; + try sema.types_pending_resolution.ensureUnusedCapacity(sema.gpa, 1); try new_decl.finalizeNewArena(&new_decl_arena); sema.types_pending_resolution.appendAssumeCapacity(union_ty); @@ -2692,7 +2692,7 @@ fn zirDeclVal(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErr } fn lookupIdentifier(sema: *Sema, block: *Scope.Block, src: LazySrcLoc, name: []const u8) !*Decl { - var namespace = sema.namespace; + var namespace = block.src_decl.namespace; while (true) { if (try sema.lookupInNamespace(block, src, namespace, name, false)) |decl| { return decl; @@ -3010,10 +3010,6 @@ fn analyzeCall( sema.inst_map = parent_inst_map; } - const parent_namespace = sema.namespace; - sema.namespace = module_fn.owner_decl.namespace; - defer sema.namespace = parent_namespace; - const parent_func = sema.func; sema.func = module_fn; defer sema.func = parent_func; @@ -3276,12 +3272,12 @@ fn analyzeCall( // Create a Decl for the new function. const src_decl = namespace.getDecl(); - const new_decl = try mod.allocateNewDecl(namespace, module_fn.owner_decl.src_node, src_decl.src_scope); // TODO better names for generic function instantiations const name_index = mod.getNextAnonNameIndex(); - new_decl.name = try std.fmt.allocPrintZ(gpa, "{s}__anon_{d}", .{ + const decl_name = try std.fmt.allocPrintZ(gpa, "{s}__anon_{d}", .{ module_fn.owner_decl.name, name_index, }); + const new_decl = try mod.allocateNewDecl(decl_name, namespace, module_fn.owner_decl.src_node, src_decl.src_scope); new_decl.src_line = module_fn.owner_decl.src_line; new_decl.is_pub = module_fn.owner_decl.is_pub; new_decl.is_exported = module_fn.owner_decl.is_exported; @@ -3311,7 +3307,6 @@ fn analyzeCall( .perm_arena = &new_decl_arena.allocator, .code = fn_zir, .owner_decl = new_decl, - .namespace = namespace, .func = null, .fn_ret_ty = Type.initTag(.void), .owner_func = null, @@ -11809,7 +11804,7 @@ pub fn resolveDeclFields(sema: *Sema, block: *Scope.Block, src: LazySrcLoc, ty: switch (ty.tag()) { .@"struct" => { const struct_obj = ty.castTag(.@"struct").?.data; - if (struct_obj.owner_decl.namespace != sema.owner_decl.namespace) return; + if (struct_obj.owner_decl.namespace.parent != sema.owner_decl.namespace) return; switch (struct_obj.status) { .none => {}, .field_types_wip => { @@ -11817,10 +11812,6 @@ pub fn resolveDeclFields(sema: *Sema, block: *Scope.Block, src: LazySrcLoc, ty: }, .have_field_types, .have_layout, .layout_wip => return, } - const prev_namespace = sema.namespace; - sema.namespace = &struct_obj.namespace; - defer sema.namespace = prev_namespace; - const old_src = block.src_decl; defer block.src_decl = old_src; block.src_decl = struct_obj.owner_decl; @@ -11831,7 +11822,7 @@ pub fn resolveDeclFields(sema: *Sema, block: *Scope.Block, src: LazySrcLoc, ty: }, .@"union", .union_tagged => { const union_obj = ty.cast(Type.Payload.Union).?.data; - if (union_obj.owner_decl.namespace != sema.owner_decl.namespace) return; + if (union_obj.owner_decl.namespace.parent != sema.owner_decl.namespace) return; switch (union_obj.status) { .none => {}, .field_types_wip => { @@ -11839,10 +11830,6 @@ pub fn resolveDeclFields(sema: *Sema, block: *Scope.Block, src: LazySrcLoc, ty: }, .have_field_types, .have_layout, .layout_wip => return, } - const prev_namespace = sema.namespace; - sema.namespace = &union_obj.namespace; - defer sema.namespace = prev_namespace; - const old_src = block.src_decl; defer block.src_decl = old_src; block.src_decl = union_obj.owner_decl; |
