aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2021-09-21 00:01:30 -0400
committerGitHub <noreply@github.com>2021-09-21 00:01:30 -0400
commit5269cbea202c6a81108390f4c47bc8a04fc6d1ff (patch)
treea95896bf83bb427953a6a33d037698e30c05d8f8 /src
parent1ad905c71e0896295d4781853cd577bbe1b4111a (diff)
parent0c74ce1156d6a967cd089cd4657575a3e22bb782 (diff)
downloadzig-5269cbea202c6a81108390f4c47bc8a04fc6d1ff.tar.gz
zig-5269cbea202c6a81108390f4c47bc8a04fc6d1ff.zip
Merge pull request #9797 from Vexu/stage2
stage2: implement cImport
Diffstat (limited to 'src')
-rw-r--r--src/AstGen.zig11
-rw-r--r--src/Compilation.zig2
-rw-r--r--src/Module.zig3
-rw-r--r--src/Sema.zig295
-rw-r--r--src/print_zir.zig18
-rw-r--r--src/type.zig2
6 files changed, 302 insertions, 29 deletions
diff --git a/src/AstGen.zig b/src/AstGen.zig
index f1eabe4c0c..176203d37f 100644
--- a/src/AstGen.zig
+++ b/src/AstGen.zig
@@ -7082,7 +7082,7 @@ fn builtinCall(
.bit_cast => return bitCast( gz, scope, rl, node, params[0], params[1]),
.TypeOf => return typeOf( gz, scope, rl, node, params),
.union_init => return unionInit(gz, scope, rl, node, params),
- .c_import => return cImport( gz, scope, rl, node, params[0]),
+ .c_import => return cImport( gz, scope, node, params[0]),
.@"export" => {
const node_tags = tree.nodes.items(.tag);
@@ -7269,6 +7269,7 @@ fn builtinCall(
return rvalue(gz, rl, result, node);
},
.c_define => {
+ if (!gz.c_import) return gz.astgen.failNode(node, "C define valid only inside C import block", .{});
const name = try comptimeExpr(gz, scope, .{ .ty = .const_slice_u8_type }, params[0]);
const value = try comptimeExpr(gz, scope, .none, params[1]);
const result = try gz.addExtendedPayload(.c_define, Zir.Inst.BinNode{
@@ -7641,6 +7642,8 @@ fn simpleCBuiltin(
operand_node: Ast.Node.Index,
tag: Zir.Inst.Extended,
) InnerError!Zir.Inst.Ref {
+ const name: []const u8 = if (tag == .c_undef) "C undef" else "C include";
+ if (!gz.c_import) return gz.astgen.failNode(node, "{s} valid only inside C import block", .{name});
const operand = try comptimeExpr(gz, scope, .{ .ty = .const_slice_u8_type }, operand_node);
_ = try gz.addExtendedPayload(tag, Zir.Inst.UnNode{
.node = gz.nodeIndexToRelative(node),
@@ -7689,7 +7692,6 @@ fn shiftOp(
fn cImport(
gz: *GenZir,
scope: *Scope,
- rl: ResultLoc,
node: Ast.Node.Index,
body_node: Ast.Node.Index,
) InnerError!Zir.Inst.Ref {
@@ -7698,6 +7700,7 @@ fn cImport(
var block_scope = gz.makeSubBlock(scope);
block_scope.force_comptime = true;
+ block_scope.c_import = true;
defer block_scope.instructions.deinit(gpa);
const block_inst = try gz.addBlock(.c_import, node);
@@ -7708,7 +7711,7 @@ fn cImport(
try block_scope.setBlockBody(block_inst);
try gz.instructions.append(gpa, block_inst);
- return rvalue(gz, rl, .void_value, node);
+ return indexToRef(block_inst);
}
fn overflowArithmetic(
@@ -9025,6 +9028,7 @@ const GenZir = struct {
base: Scope = Scope{ .tag = base_tag },
force_comptime: bool,
in_defer: bool,
+ c_import: bool = false,
/// How decls created in this scope should be named.
anon_name_strategy: Zir.Inst.NameStrategy = .anon,
/// The containing decl AST node.
@@ -9070,6 +9074,7 @@ const GenZir = struct {
return .{
.force_comptime = gz.force_comptime,
.in_defer = gz.in_defer,
+ .c_import = gz.c_import,
.decl_node_index = gz.decl_node_index,
.decl_line = gz.decl_line,
.parent = scope,
diff --git a/src/Compilation.zig b/src/Compilation.zig
index c1dfe91dc2..53e643acb8 100644
--- a/src/Compilation.zig
+++ b/src/Compilation.zig
@@ -2644,7 +2644,7 @@ pub fn cImport(comp: *Compilation, c_src: []const u8) !CImportResult {
const dep_basename = std.fs.path.basename(out_dep_path);
try man.addDepFilePost(zig_cache_tmp_dir, dep_basename);
- try comp.stage1_cache_manifest.addDepFilePost(zig_cache_tmp_dir, dep_basename);
+ if (build_options.is_stage1 and comp.bin_file.options.use_stage1) try comp.stage1_cache_manifest.addDepFilePost(zig_cache_tmp_dir, dep_basename);
const digest = man.final();
const o_sub_path = try std.fs.path.join(arena, &[_][]const u8{ "o", &digest });
diff --git a/src/Module.zig b/src/Module.zig
index 500c34bcb0..6a183db21f 100644
--- a/src/Module.zig
+++ b/src/Module.zig
@@ -1325,6 +1325,8 @@ pub const Scope = struct {
/// when null, it is determined by build mode, changed by @setRuntimeSafety
want_safety: ?bool = null,
+ c_import_buf: ?*std.ArrayList(u8) = null,
+
const Param = struct {
/// `noreturn` means `anytype`.
ty: Type,
@@ -1377,6 +1379,7 @@ pub const Scope = struct {
.runtime_loop = parent.runtime_loop,
.runtime_index = parent.runtime_index,
.want_safety = parent.want_safety,
+ .c_import_buf = parent.c_import_buf,
};
}
diff --git a/src/Sema.zig b/src/Sema.zig
index ff32ce49ca..786db21b4a 100644
--- a/src/Sema.zig
+++ b/src/Sema.zig
@@ -83,6 +83,7 @@ const Decl = Module.Decl;
const LazySrcLoc = Module.LazySrcLoc;
const RangeSet = @import("RangeSet.zig");
const target_util = @import("target.zig");
+const Package = @import("Package.zig");
pub const InstMap = std.AutoHashMapUnmanaged(Zir.Inst.Index, Air.Inst.Ref);
@@ -2138,10 +2139,77 @@ fn zirCImport(sema: *Sema, parent_block: *Scope.Block, inst: Zir.Inst.Index) Com
const tracy = trace(@src());
defer tracy.end();
- const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
- const src = inst_data.src();
+ const pl_node = sema.code.instructions.items(.data)[inst].pl_node;
+ const src = pl_node.src();
+ const extra = sema.code.extraData(Zir.Inst.Block, pl_node.payload_index);
+ const body = sema.code.extra[extra.end..][0..extra.data.body_len];
+
+ // we check this here to avoid undefined symbols
+ if (!@import("build_options").have_llvm)
+ return sema.mod.fail(&parent_block.base, src, "cannot do C import on Zig compiler not built with LLVM-extension", .{});
+
+ var c_import_buf = std.ArrayList(u8).init(sema.gpa);
+ defer c_import_buf.deinit();
+
+ var child_block: Scope.Block = .{
+ .parent = parent_block,
+ .sema = sema,
+ .src_decl = parent_block.src_decl,
+ .instructions = .{},
+ .inlining = parent_block.inlining,
+ .is_comptime = parent_block.is_comptime,
+ .c_import_buf = &c_import_buf,
+ };
+ defer child_block.instructions.deinit(sema.gpa);
+
+ _ = try sema.analyzeBody(&child_block, body);
+
+ const c_import_res = sema.mod.comp.cImport(c_import_buf.items) catch |err|
+ return sema.mod.fail(&child_block.base, src, "C import failed: {s}", .{@errorName(err)});
+
+ if (c_import_res.errors.len != 0) {
+ const msg = msg: {
+ const msg = try sema.mod.errMsg(&child_block.base, src, "C import failed", .{});
+ errdefer msg.destroy(sema.gpa);
+
+ if (!sema.mod.comp.bin_file.options.link_libc)
+ try sema.mod.errNote(&child_block.base, src, msg, "libc headers not available; compilation does not link against libc", .{});
+
+ for (c_import_res.errors) |_| {
+ // TODO integrate with LazySrcLoc
+ // try sema.mod.errNoteNonLazy(.{}, msg, "{s}", .{clang_err.msg_ptr[0..clang_err.msg_len]});
+ // if (clang_err.filename_ptr) |p| p[0..clang_err.filename_len] else "(no file)",
+ // clang_err.line + 1,
+ // clang_err.column + 1,
+ }
+ @import("clang.zig").Stage2ErrorMsg.delete(c_import_res.errors.ptr, c_import_res.errors.len);
+ break :msg msg;
+ };
+ return sema.mod.failWithOwnedErrorMsg(&child_block.base, msg);
+ }
+ const c_import_pkg = Package.create(
+ sema.gpa,
+ null,
+ c_import_res.out_zig_path,
+ ) catch |err| switch (err) {
+ error.OutOfMemory => return error.OutOfMemory,
+ else => unreachable, // we pass null for root_src_dir_path
+ };
+ const std_pkg = sema.mod.main_pkg.table.get("std").?;
+ const builtin_pkg = sema.mod.main_pkg.table.get("builtin").?;
+ try c_import_pkg.add(sema.gpa, "builtin", builtin_pkg);
+ try c_import_pkg.add(sema.gpa, "std", std_pkg);
+
+ const result = sema.mod.importPkg(c_import_pkg) catch |err|
+ return sema.mod.fail(&child_block.base, src, "C import failed: {s}", .{@errorName(err)});
+
+ sema.mod.astGenFile(result.file) catch |err|
+ return sema.mod.fail(&child_block.base, src, "C import failed: {s}", .{@errorName(err)});
- return sema.mod.fail(&parent_block.base, src, "TODO: implement Sema.zirCImport", .{});
+ try sema.mod.semaFile(result.file);
+ const file_root_decl = result.file.root_decl.?;
+ try sema.mod.declareDeclDependency(sema.owner_decl, file_root_decl);
+ return sema.addType(file_root_decl.ty);
}
fn zirSuspendBlock(sema: *Sema, parent_block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
@@ -6405,10 +6473,41 @@ fn runtimeBoolCmp(
fn zirSizeOf(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
const inst_data = sema.code.instructions.items(.data)[inst].un_node;
+ const src = inst_data.src();
const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
const operand_ty = try sema.resolveType(block, operand_src, inst_data.operand);
const target = sema.mod.getTarget();
- const abi_size = operand_ty.abiSize(target);
+ const abi_size = switch (operand_ty.zigTypeTag()) {
+ .Fn => unreachable,
+ .NoReturn,
+ .Undefined,
+ .Null,
+ .BoundFn,
+ .Opaque,
+ => return sema.mod.fail(&block.base, src, "no size available for type '{}'", .{operand_ty}),
+ .Type,
+ .EnumLiteral,
+ .ComptimeFloat,
+ .ComptimeInt,
+ .Void,
+ => 0,
+
+ .Bool,
+ .Int,
+ .Float,
+ .Pointer,
+ .Array,
+ .Struct,
+ .Optional,
+ .ErrorUnion,
+ .ErrorSet,
+ .Enum,
+ .Union,
+ .Vector,
+ .Frame,
+ .AnyFrame,
+ => operand_ty.abiSize(target),
+ };
return sema.addIntUnsigned(Type.initTag(.comptime_int), abi_size);
}
@@ -6456,19 +6555,80 @@ fn zirTypeInfo(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileEr
const target = sema.mod.getTarget();
switch (ty.zigTypeTag()) {
+ .Type => return sema.addConstant(
+ type_info_ty,
+ try Value.Tag.@"union".create(sema.arena, .{
+ .tag = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(std.builtin.TypeId.Type)),
+ .val = Value.initTag(.unreachable_value),
+ }),
+ ),
+ .Void => return sema.addConstant(
+ type_info_ty,
+ try Value.Tag.@"union".create(sema.arena, .{
+ .tag = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(std.builtin.TypeId.Void)),
+ .val = Value.initTag(.unreachable_value),
+ }),
+ ),
+ .Bool => return sema.addConstant(
+ type_info_ty,
+ try Value.Tag.@"union".create(sema.arena, .{
+ .tag = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(std.builtin.TypeId.Bool)),
+ .val = Value.initTag(.unreachable_value),
+ }),
+ ),
+ .NoReturn => return sema.addConstant(
+ type_info_ty,
+ try Value.Tag.@"union".create(sema.arena, .{
+ .tag = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(std.builtin.TypeId.NoReturn)),
+ .val = Value.initTag(.unreachable_value),
+ }),
+ ),
+ .ComptimeFloat => return sema.addConstant(
+ type_info_ty,
+ try Value.Tag.@"union".create(sema.arena, .{
+ .tag = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(std.builtin.TypeId.ComptimeFloat)),
+ .val = Value.initTag(.unreachable_value),
+ }),
+ ),
+ .ComptimeInt => return sema.addConstant(
+ type_info_ty,
+ try Value.Tag.@"union".create(sema.arena, .{
+ .tag = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(std.builtin.TypeId.ComptimeInt)),
+ .val = Value.initTag(.unreachable_value),
+ }),
+ ),
+ .Undefined => return sema.addConstant(
+ type_info_ty,
+ try Value.Tag.@"union".create(sema.arena, .{
+ .tag = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(std.builtin.TypeId.Undefined)),
+ .val = Value.initTag(.unreachable_value),
+ }),
+ ),
+ .Null => return sema.addConstant(
+ type_info_ty,
+ try Value.Tag.@"union".create(sema.arena, .{
+ .tag = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(std.builtin.TypeId.Null)),
+ .val = Value.initTag(.unreachable_value),
+ }),
+ ),
+ .EnumLiteral => return sema.addConstant(
+ type_info_ty,
+ try Value.Tag.@"union".create(sema.arena, .{
+ .tag = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(std.builtin.TypeId.EnumLiteral)),
+ .val = Value.initTag(.unreachable_value),
+ }),
+ ),
.Fn => {
+ const info = ty.fnInfo();
const field_values = try sema.arena.alloc(Value, 6);
// calling_convention: CallingConvention,
- field_values[0] = try Value.Tag.enum_field_index.create(
- sema.arena,
- @enumToInt(ty.fnCallingConvention()),
- );
+ field_values[0] = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(info.cc));
// alignment: comptime_int,
field_values[1] = try Value.Tag.int_u64.create(sema.arena, ty.abiAlignment(target));
// is_generic: bool,
- field_values[2] = Value.initTag(.bool_false); // TODO
+ field_values[2] = if (info.is_generic) Value.initTag(.bool_true) else Value.initTag(.bool_false);
// is_var_args: bool,
- field_values[3] = Value.initTag(.bool_false); // TODO
+ field_values[3] = if (info.is_var_args) Value.initTag(.bool_true) else Value.initTag(.bool_false);
// return_type: ?type,
field_values[4] = try Value.Tag.ty.create(sema.arena, ty.fnReturnType());
// args: []const FnArg,
@@ -6477,10 +6637,7 @@ fn zirTypeInfo(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileEr
return sema.addConstant(
type_info_ty,
try Value.Tag.@"union".create(sema.arena, .{
- .tag = try Value.Tag.enum_field_index.create(
- sema.arena,
- @enumToInt(@typeInfo(std.builtin.TypeInfo).Union.tag_type.?.Fn),
- ),
+ .tag = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(std.builtin.TypeId.Fn)),
.val = try Value.Tag.@"struct".create(sema.arena, field_values),
}),
);
@@ -6499,10 +6656,92 @@ fn zirTypeInfo(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileEr
return sema.addConstant(
type_info_ty,
try Value.Tag.@"union".create(sema.arena, .{
- .tag = try Value.Tag.enum_field_index.create(
- sema.arena,
- @enumToInt(@typeInfo(std.builtin.TypeInfo).Union.tag_type.?.Int),
- ),
+ .tag = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(std.builtin.TypeId.Int)),
+ .val = try Value.Tag.@"struct".create(sema.arena, field_values),
+ }),
+ );
+ },
+ .Float => {
+ const field_values = try sema.arena.alloc(Value, 1);
+ // bits: comptime_int,
+ field_values[0] = try Value.Tag.int_u64.create(sema.arena, ty.bitSize(target));
+
+ return sema.addConstant(
+ type_info_ty,
+ try Value.Tag.@"union".create(sema.arena, .{
+ .tag = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(std.builtin.TypeId.Float)),
+ .val = try Value.Tag.@"struct".create(sema.arena, field_values),
+ }),
+ );
+ },
+ .Pointer => {
+ const info = ty.ptrInfo().data;
+ const field_values = try sema.arena.alloc(Value, 7);
+ // size: Size,
+ field_values[0] = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(info.size));
+ // is_const: bool,
+ field_values[1] = if (!info.mutable) Value.initTag(.bool_true) else Value.initTag(.bool_false);
+ // is_volatile: bool,
+ field_values[2] = if (info.@"volatile") Value.initTag(.bool_true) else Value.initTag(.bool_false);
+ // alignment: comptime_int,
+ field_values[3] = try Value.Tag.int_u64.create(sema.arena, info.@"align");
+ // child: type,
+ field_values[4] = try Value.Tag.ty.create(sema.arena, info.pointee_type);
+ // is_allowzero: bool,
+ field_values[5] = if (info.@"allowzero") Value.initTag(.bool_true) else Value.initTag(.bool_false);
+ // sentinel: anytype,
+ field_values[6] = if (info.sentinel) |some| try Value.Tag.opt_payload.create(sema.arena, some) else Value.initTag(.null_value);
+
+ return sema.addConstant(
+ type_info_ty,
+ try Value.Tag.@"union".create(sema.arena, .{
+ .tag = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(std.builtin.TypeId.Pointer)),
+ .val = try Value.Tag.@"struct".create(sema.arena, field_values),
+ }),
+ );
+ },
+ .Array => {
+ const info = ty.arrayInfo();
+ const field_values = try sema.arena.alloc(Value, 3);
+ // len: comptime_int,
+ field_values[0] = try Value.Tag.int_u64.create(sema.arena, info.len);
+ // child: type,
+ field_values[1] = try Value.Tag.ty.create(sema.arena, info.elem_type);
+ // sentinel: anytype,
+ field_values[2] = if (info.sentinel) |some| try Value.Tag.opt_payload.create(sema.arena, some) else Value.initTag(.null_value);
+
+ return sema.addConstant(
+ type_info_ty,
+ try Value.Tag.@"union".create(sema.arena, .{
+ .tag = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(std.builtin.TypeId.Array)),
+ .val = try Value.Tag.@"struct".create(sema.arena, field_values),
+ }),
+ );
+ },
+ .Optional => {
+ const field_values = try sema.arena.alloc(Value, 1);
+ // child: type,
+ field_values[0] = try Value.Tag.ty.create(sema.arena, try ty.optionalChildAlloc(sema.arena));
+
+ return sema.addConstant(
+ type_info_ty,
+ try Value.Tag.@"union".create(sema.arena, .{
+ .tag = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(std.builtin.TypeId.Optional)),
+ .val = try Value.Tag.@"struct".create(sema.arena, field_values),
+ }),
+ );
+ },
+ .ErrorUnion => {
+ const field_values = try sema.arena.alloc(Value, 2);
+ // error_set: type,
+ field_values[0] = try Value.Tag.ty.create(sema.arena, ty.errorUnionSet());
+ // payload: type,
+ field_values[1] = try Value.Tag.ty.create(sema.arena, ty.errorUnionPayload());
+
+ return sema.addConstant(
+ type_info_ty,
+ try Value.Tag.@"union".create(sema.arena, .{
+ .tag = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(std.builtin.TypeId.ErrorUnion)),
.val = try Value.Tag.@"struct".create(sema.arena, field_values),
}),
);
@@ -8226,7 +8465,10 @@ fn zirCUndef(
) CompileError!Air.Inst.Ref {
const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
const src: LazySrcLoc = .{ .node_offset = extra.node };
- return sema.mod.fail(&block.base, src, "TODO: implement Sema.zirCUndef", .{});
+
+ const name = try sema.resolveConstString(block, src, extra.operand);
+ try block.c_import_buf.?.writer().print("#undefine {s}\n", .{name});
+ return Air.Inst.Ref.void_value;
}
fn zirCInclude(
@@ -8236,7 +8478,10 @@ fn zirCInclude(
) CompileError!Air.Inst.Ref {
const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
const src: LazySrcLoc = .{ .node_offset = extra.node };
- return sema.mod.fail(&block.base, src, "TODO: implement Sema.zirCInclude", .{});
+
+ const name = try sema.resolveConstString(block, src, extra.operand);
+ try block.c_import_buf.?.writer().print("#include <{s}>\n", .{name});
+ return Air.Inst.Ref.void_value;
}
fn zirCDefine(
@@ -8246,7 +8491,15 @@ fn zirCDefine(
) CompileError!Air.Inst.Ref {
const extra = sema.code.extraData(Zir.Inst.BinNode, extended.operand).data;
const src: LazySrcLoc = .{ .node_offset = extra.node };
- return sema.mod.fail(&block.base, src, "TODO: implement Sema.zirCDefine", .{});
+
+ const name = try sema.resolveConstString(block, src, extra.lhs);
+ if (sema.typeOf(extra.rhs).zigTypeTag() != .Void) {
+ const value = try sema.resolveConstString(block, src, extra.rhs);
+ try block.c_import_buf.?.writer().print("#define {s} {s}\n", .{ name, value });
+ } else {
+ try block.c_import_buf.?.writer().print("#define {s}\n", .{name});
+ }
+ return Air.Inst.Ref.void_value;
}
fn zirWasmMemorySize(
diff --git a/src/print_zir.zig b/src/print_zir.zig
index 94fa0307bd..35b3da4479 100644
--- a/src/print_zir.zig
+++ b/src/print_zir.zig
@@ -407,15 +407,27 @@ const Writer = struct {
.mul_with_saturation,
.shl_with_saturation,
=> try self.writeSaturatingArithmetic(stream, extended),
+
.struct_decl => try self.writeStructDecl(stream, extended),
.union_decl => try self.writeUnionDecl(stream, extended),
.enum_decl => try self.writeEnumDecl(stream, extended),
+ .c_undef, .c_include => {
+ const inst_data = self.code.extraData(Zir.Inst.UnNode, extended.operand).data;
+ try self.writeInstRef(stream, inst_data.operand);
+ try stream.writeAll(") ");
+ },
+
+ .c_define => {
+ const inst_data = self.code.extraData(Zir.Inst.BinNode, extended.operand).data;
+ try self.writeInstRef(stream, inst_data.lhs);
+ try stream.writeAll(", ");
+ try self.writeInstRef(stream, inst_data.rhs);
+ try stream.writeByte(')');
+ },
+
.alloc,
.builtin_extern,
- .c_undef,
- .c_include,
- .c_define,
.wasm_memory_size,
.wasm_memory_grow,
=> try stream.writeAll("TODO))"),
diff --git a/src/type.zig b/src/type.zig
index db193639a7..5d184ed2fc 100644
--- a/src/type.zig
+++ b/src/type.zig
@@ -602,8 +602,8 @@ pub const Type = extern union {
}
return false;
},
+ .Float => return a.tag() == b.tag(),
.Opaque,
- .Float,
.BoundFn,
.Frame,
=> std.debug.panic("TODO implement Type equality comparison of {} and {}", .{ a, b }),