aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/AstGen.zig4
-rw-r--r--src/Sema.zig17
-rw-r--r--src/TypedValue.zig50
3 files changed, 63 insertions, 8 deletions
diff --git a/src/AstGen.zig b/src/AstGen.zig
index 4e571ffda9..c9f44a6216 100644
--- a/src/AstGen.zig
+++ b/src/AstGen.zig
@@ -8455,8 +8455,12 @@ fn simpleUnOp(
operand_node: Ast.Node.Index,
tag: Zir.Inst.Tag,
) InnerError!Zir.Inst.Ref {
+ const prev_force_comptime = gz.force_comptime;
+ defer gz.force_comptime = prev_force_comptime;
+
switch (tag) {
.tag_name, .error_name, .ptr_to_int => try emitDbgNode(gz, node),
+ .compile_error => gz.force_comptime = true,
else => {},
}
const operand = try expr(gz, scope, operand_ri, operand_node);
diff --git a/src/Sema.zig b/src/Sema.zig
index 68348ac161..3edc35aeb6 100644
--- a/src/Sema.zig
+++ b/src/Sema.zig
@@ -5405,6 +5405,13 @@ fn zirExport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
},
else => |e| return e,
};
+ {
+ try sema.mod.ensureDeclAnalyzed(decl_index);
+ const exported_decl = sema.mod.declPtr(decl_index);
+ if (exported_decl.val.castTag(.function)) |some| {
+ return sema.analyzeExport(block, src, options, some.data.owner_decl);
+ }
+ }
try sema.analyzeExport(block, src, options, decl_index);
}
@@ -17870,6 +17877,13 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
operand_ty.fmt(mod),
}),
};
+ if (enum_ty.enumFieldCount() == 0) {
+ // TODO I don't think this is the correct way to handle this but
+ // it prevents a crash.
+ return sema.fail(block, operand_src, "cannot get @tagName of empty enum '{}'", .{
+ enum_ty.fmt(mod),
+ });
+ }
const enum_decl_index = enum_ty.getOwnerDecl();
const casted_operand = try sema.coerce(block, enum_ty, operand, operand_src);
if (try sema.resolveDefinedValue(block, operand_src, casted_operand)) |val| {
@@ -20997,6 +21011,9 @@ fn analyzeMinMax(
if (rhs_val.isUndef()) return sema.addConstUndef(simd_op.result_ty);
+ try sema.resolveLazyValue(lhs_val);
+ try sema.resolveLazyValue(rhs_val);
+
const opFunc = switch (air_tag) {
.min => Value.numberMin,
.max => Value.numberMax,
diff --git a/src/TypedValue.zig b/src/TypedValue.zig
index 619fb003f9..10ab88b866 100644
--- a/src/TypedValue.zig
+++ b/src/TypedValue.zig
@@ -46,6 +46,7 @@ pub fn enumToInt(tv: TypedValue, buffer: *Value.Payload.U64) Value {
}
const max_aggregate_items = 100;
+const max_string_len = 256;
const FormatContext = struct {
tv: TypedValue,
@@ -141,10 +142,12 @@ pub fn print(
.extern_options_type => return writer.writeAll("std.builtin.ExternOptions"),
.type_info_type => return writer.writeAll("std.builtin.Type"),
- .empty_struct_value, .aggregate => {
+ .empty_struct_value => return writer.writeAll(".{}"),
+ .aggregate => {
if (level == 0) {
return writer.writeAll(".{ ... }");
}
+ const values = val.castTag(.aggregate).?;
if (ty.zigTypeTag() == .Struct) {
try writer.writeAll(".{");
const max_len = std.math.min(ty.structFieldCount(), max_aggregate_items);
@@ -159,9 +162,9 @@ pub fn print(
try print(.{
.ty = ty.structFieldType(i),
.val = switch (ty.containerLayout()) {
- .Packed => val.castTag(.aggregate).?.data[i],
+ .Packed => values.data[i],
else => ty.structFieldValueComptime(i) orelse b: {
- const vals = val.castTag(.aggregate).?.data;
+ const vals = values.data;
break :b vals[i];
},
},
@@ -172,17 +175,31 @@ pub fn print(
}
return writer.writeAll("}");
} else {
- try writer.writeAll(".{ ");
const elem_ty = ty.elemType2();
const len = ty.arrayLen();
- const max_len = std.math.min(len, max_aggregate_items);
+ if (elem_ty.eql(Type.u8, mod)) str: {
+ const max_len = @intCast(usize, std.math.min(len, max_string_len));
+ var buf: [max_string_len]u8 = undefined;
+
+ var i: u32 = 0;
+ while (i < max_len) : (i += 1) {
+ buf[i] = std.math.cast(u8, values.data[i].toUnsignedInt(target)) orelse break :str;
+ }
+
+ const truncated = if (len > max_string_len) " (truncated)" else "";
+ return writer.print("\"{}{s}\"", .{ std.zig.fmtEscapes(buf[0..max_len]), truncated });
+ }
+
+ try writer.writeAll(".{ ");
+
+ const max_len = std.math.min(len, max_aggregate_items);
var i: u32 = 0;
while (i < max_len) : (i += 1) {
if (i != 0) try writer.writeAll(", ");
try print(.{
.ty = elem_ty,
- .val = val.castTag(.aggregate).?.data[i],
+ .val = values.data[i],
}, writer, level - 1, mod);
}
if (len > max_aggregate_items) {
@@ -372,11 +389,28 @@ pub fn print(
return writer.writeAll(".{ ... }");
}
const payload = val.castTag(.slice).?.data;
- try writer.writeAll(".{ ");
const elem_ty = ty.elemType2();
const len = payload.len.toUnsignedInt(target);
- const max_len = std.math.min(len, max_aggregate_items);
+ if (elem_ty.eql(Type.u8, mod)) str: {
+ const max_len = @intCast(usize, std.math.min(len, max_string_len));
+ var buf: [max_string_len]u8 = undefined;
+
+ var i: u32 = 0;
+ while (i < max_len) : (i += 1) {
+ var elem_buf: Value.ElemValueBuffer = undefined;
+ const elem_val = payload.ptr.elemValueBuffer(mod, i, &elem_buf);
+ buf[i] = std.math.cast(u8, elem_val.toUnsignedInt(target)) orelse break :str;
+ }
+
+ // TODO would be nice if this had a bit of unicode awareness.
+ const truncated = if (len > max_string_len) " (truncated)" else "";
+ return writer.print("\"{}{s}\"", .{ std.zig.fmtEscapes(buf[0..max_len]), truncated });
+ }
+
+ try writer.writeAll(".{ ");
+
+ const max_len = std.math.min(len, max_aggregate_items);
var i: u32 = 0;
while (i < max_len) : (i += 1) {
if (i != 0) try writer.writeAll(", ");