Skip to content

Commit 6a98d03

Browse files
committed
Supports lowering structs without a result type
1 parent 2811a06 commit 6a98d03

File tree

2 files changed

+77
-3
lines changed

2 files changed

+77
-3
lines changed

src/Sema.zig

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2999,7 +2999,7 @@ fn zirStructDecl(
29992999
return Air.internedToRef(wip_ty.finish(ip, new_namespace_index));
30003000
}
30013001

3002-
fn createTypeName(
3002+
pub fn createTypeName(
30033003
sema: *Sema,
30043004
block: *Block,
30053005
name_strategy: Zir.Inst.NameStrategy,
@@ -32179,7 +32179,7 @@ fn addReferenceEntry(
3217932179
try zcu.addUnitReference(sema.owner, referenced_unit, src);
3218032180
}
3218132181

32182-
fn addTypeReferenceEntry(
32182+
pub fn addTypeReferenceEntry(
3218332183
sema: *Sema,
3218432184
src: LazySrcLoc,
3218532185
referenced_type: InternPool.Index,

src/Sema/LowerZon.zig

Lines changed: 75 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,81 @@ fn lowerExprAnonResTy(self: *LowerZon, node: Zoir.Node.Index) CompileError!Inter
138138
.storage = .{ .elems = values },
139139
} });
140140
},
141-
.struct_literal => @panic("unimplemented"),
141+
.struct_literal => |init| {
142+
const struct_ty = switch (try ip.getStructType(
143+
gpa,
144+
pt.tid,
145+
.{
146+
.layout = .auto,
147+
.fields_len = @intCast(init.names.len),
148+
.known_non_opv = false,
149+
.requires_comptime = .no,
150+
.any_comptime_fields = true,
151+
.any_default_inits = true,
152+
.inits_resolved = true,
153+
.any_aligned_fields = false,
154+
.key = .{ .reified = .{
155+
.zir_index = self.base_node_inst,
156+
.type_hash = @intFromEnum(node),
157+
} },
158+
},
159+
false,
160+
)) {
161+
.wip => |wip| ty: {
162+
errdefer wip.cancel(ip, pt.tid);
163+
wip.setName(ip, try self.sema.createTypeName(
164+
self.block,
165+
.anon,
166+
"struct",
167+
self.base_node_inst.resolve(ip),
168+
wip.index,
169+
));
170+
171+
const struct_type = ip.loadStructType(wip.index);
172+
173+
for (init.names, 0..) |name, field_idx| {
174+
const name_interned = try ip.getOrPutString(
175+
gpa,
176+
pt.tid,
177+
name.get(self.file.zoir.?),
178+
.no_embedded_nulls,
179+
);
180+
assert(struct_type.addFieldName(ip, name_interned) == null);
181+
struct_type.setFieldComptime(ip, field_idx);
182+
}
183+
184+
const values = struct_type.field_inits.get(ip);
185+
const types = struct_type.field_types.get(ip);
186+
for (0..init.names.len) |i| {
187+
values[i] = try self.lowerExprAnonResTy(init.vals.at(@intCast(i)));
188+
types[i] = Value.fromInterned(values[i]).typeOf(pt.zcu).toIntern();
189+
}
190+
191+
const new_namespace_index = try pt.createNamespace(.{
192+
.parent = self.block.namespace.toOptional(),
193+
.owner_type = wip.index,
194+
.file_scope = self.block.getFileScopeIndex(pt.zcu),
195+
.generation = pt.zcu.generation,
196+
});
197+
try pt.zcu.comp.queueJob(.{ .resolve_type_fully = wip.index });
198+
codegen_type: {
199+
if (pt.zcu.comp.config.use_llvm) break :codegen_type;
200+
if (self.block.ownerModule().strip) break :codegen_type;
201+
try pt.zcu.comp.queueJob(.{ .codegen_type = wip.index });
202+
}
203+
break :ty wip.finish(ip, new_namespace_index);
204+
},
205+
.existing => |ty| ty,
206+
};
207+
try self.sema.declareDependency(.{ .interned = struct_ty });
208+
try self.sema.addTypeReferenceEntry(self.nodeSrc(node), struct_ty);
209+
210+
const elems = ip.loadStructType(struct_ty).field_inits.get(ip);
211+
return try pt.intern(.{ .aggregate = .{
212+
.ty = struct_ty,
213+
.storage = .{ .elems = elems },
214+
} });
215+
},
142216
}
143217
}
144218

0 commit comments

Comments
 (0)