aboutsummaryrefslogtreecommitdiff
path: root/src/Sema.zig
diff options
context:
space:
mode:
authorVeikka Tuominen <git@vexu.eu>2023-01-10 21:54:58 +0200
committerVeikka Tuominen <git@vexu.eu>2023-01-11 21:11:21 +0200
commitd8128c272a087bbfc0b33a786c18267f49cd4982 (patch)
tree2db7e2c6b4bb59ea23826703e2926b89cf630efc /src/Sema.zig
parent1658e4893d749c7d1ed378cd34b6cbe1a132c0e9 (diff)
downloadzig-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.zig77
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 {