diff options
| author | Veikka Tuominen <git@vexu.eu> | 2023-01-10 21:54:58 +0200 |
|---|---|---|
| committer | Veikka Tuominen <git@vexu.eu> | 2023-01-11 21:11:21 +0200 |
| commit | d8128c272a087bbfc0b33a786c18267f49cd4982 (patch) | |
| tree | 2db7e2c6b4bb59ea23826703e2926b89cf630efc /src/Sema.zig | |
| parent | 1658e4893d749c7d1ed378cd34b6cbe1a132c0e9 (diff) | |
| download | zig-d8128c272a087bbfc0b33a786c18267f49cd4982.tar.gz zig-d8128c272a087bbfc0b33a786c18267f49cd4982.zip | |
Sema: fix typeInfo decls with usingnamespace
Closes #12403
Diffstat (limited to 'src/Sema.zig')
| -rw-r--r-- | src/Sema.zig | 77 |
1 files changed, 52 insertions, 25 deletions
diff --git a/src/Sema.zig b/src/Sema.zig index 8263468fbf..3db5eb5ba1 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -16217,11 +16217,54 @@ fn typeInfoDecls( }; try sema.queueFullTypeResolution(try declaration_ty.copy(sema.arena)); - const decls_len = if (opt_namespace) |ns| ns.decls.count() else 0; - const decls_vals = try decls_anon_decl.arena().alloc(Value, decls_len); - for (decls_vals) |*decls_val, i| { - const decl_index = opt_namespace.?.decls.keys()[i]; + var decl_vals = std.ArrayList(Value).init(sema.gpa); + defer decl_vals.deinit(); + + var seen_namespaces = std.AutoHashMap(*Namespace, void).init(sema.gpa); + defer seen_namespaces.deinit(); + + if (opt_namespace) |some| { + try sema.typeInfoNamespaceDecls(block, decls_anon_decl.arena(), some, &decl_vals, &seen_namespaces); + } + + const new_decl = try decls_anon_decl.finish( + try Type.Tag.array.create(decls_anon_decl.arena(), .{ + .len = decl_vals.items.len, + .elem_type = declaration_ty, + }), + try Value.Tag.aggregate.create( + decls_anon_decl.arena(), + try decls_anon_decl.arena().dupe(Value, decl_vals.items), + ), + 0, // default alignment + ); + return try Value.Tag.slice.create(sema.arena, .{ + .ptr = try Value.Tag.decl_ref.create(sema.arena, new_decl), + .len = try Value.Tag.int_u64.create(sema.arena, decl_vals.items.len), + }); +} + +fn typeInfoNamespaceDecls( + sema: *Sema, + block: *Block, + decls_anon_decl: Allocator, + namespace: *Namespace, + decl_vals: *std.ArrayList(Value), + seen_namespaces: *std.AutoHashMap(*Namespace, void), +) !void { + const gop = try seen_namespaces.getOrPut(namespace); + if (gop.found_existing) return; + const decls = namespace.decls.keys(); + for (decls) |decl_index| { const decl = sema.mod.declPtr(decl_index); + if (decl.kind == .@"usingnamespace") { + try sema.mod.ensureDeclAnalyzed(decl_index); + var buf: Value.ToTypeBuffer = undefined; + const new_ns = decl.val.toType(&buf).getNamespace().?; + try sema.typeInfoNamespaceDecls(block, decls_anon_decl, new_ns, decl_vals, seen_namespaces); + continue; + } + if (decl.kind != .named) continue; const name_val = v: { var anon_decl = try block.startAnonDecl(); defer anon_decl.deinit(); @@ -16231,37 +16274,21 @@ fn typeInfoDecls( try Value.Tag.bytes.create(anon_decl.arena(), bytes[0 .. bytes.len + 1]), 0, // default alignment ); - break :v try Value.Tag.slice.create(decls_anon_decl.arena(), .{ - .ptr = try Value.Tag.decl_ref.create(decls_anon_decl.arena(), new_decl), - .len = try Value.Tag.int_u64.create(decls_anon_decl.arena(), bytes.len), + break :v try Value.Tag.slice.create(decls_anon_decl, .{ + .ptr = try Value.Tag.decl_ref.create(decls_anon_decl, new_decl), + .len = try Value.Tag.int_u64.create(decls_anon_decl, bytes.len), }); }; - const fields = try decls_anon_decl.arena().create([2]Value); + const fields = try decls_anon_decl.create([2]Value); fields.* = .{ //name: []const u8, name_val, //is_pub: bool, Value.makeBool(decl.is_pub), }; - decls_val.* = try Value.Tag.aggregate.create(decls_anon_decl.arena(), fields); + try decl_vals.append(try Value.Tag.aggregate.create(decls_anon_decl, fields)); } - - const new_decl = try decls_anon_decl.finish( - try Type.Tag.array.create(decls_anon_decl.arena(), .{ - .len = decls_vals.len, - .elem_type = declaration_ty, - }), - try Value.Tag.aggregate.create( - decls_anon_decl.arena(), - try decls_anon_decl.arena().dupe(Value, decls_vals), - ), - 0, // default alignment - ); - return try Value.Tag.slice.create(sema.arena, .{ - .ptr = try Value.Tag.decl_ref.create(sema.arena, new_decl), - .len = try Value.Tag.int_u64.create(sema.arena, decls_vals.len), - }); } fn zirTypeof(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
