aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVeikka Tuominen <git@vexu.eu>2023-01-18 12:56:48 +0200
committerVeikka Tuominen <git@vexu.eu>2023-01-22 00:12:36 +0200
commitd284c00fda45b943f4ed5244ae1cb9e7f90f481f (patch)
treebfec199eade94e25e173b0150b565bd1123f7764
parent7f635ae7bdf63da19d09763c7fdbdc61fa035282 (diff)
downloadzig-d284c00fda45b943f4ed5244ae1cb9e7f90f481f.tar.gz
zig-d284c00fda45b943f4ed5244ae1cb9e7f90f481f.zip
Sema: handle lazy values in more places
* resolve lazy values in anon structs being passed to anytype params * use `resolveMaybeUndefValIntable` where appropriate Closes #14356
-rw-r--r--src/Sema.zig18
-rw-r--r--test/behavior.zig1
-rw-r--r--test/behavior/bugs/12488.zig13
-rw-r--r--test/behavior/fn.zig23
4 files changed, 32 insertions, 23 deletions
diff --git a/src/Sema.zig b/src/Sema.zig
index dcc38e4c0a..8da24b72cc 100644
--- a/src/Sema.zig
+++ b/src/Sema.zig
@@ -7514,7 +7514,7 @@ fn resolveGenericInstantiationType(
}
fn resolveTupleLazyValues(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError!void {
- if (!ty.isSimpleTuple()) return;
+ if (!ty.isSimpleTupleOrAnonStruct()) return;
const tuple = ty.tupleFields();
for (tuple.values) |field_val, i| {
try sema.resolveTupleLazyValues(block, src, tuple.types[i]);
@@ -11771,8 +11771,8 @@ fn zirShl(
// TODO coerce rhs if air_tag is not shl_sat
const rhs_is_comptime_int = try sema.checkIntType(block, rhs_src, scalar_rhs_ty);
- const maybe_lhs_val = try sema.resolveMaybeUndefVal(lhs);
- const maybe_rhs_val = try sema.resolveMaybeUndefVal(rhs);
+ const maybe_lhs_val = try sema.resolveMaybeUndefValIntable(lhs);
+ const maybe_rhs_val = try sema.resolveMaybeUndefValIntable(rhs);
if (maybe_rhs_val) |rhs_val| {
if (rhs_val.isUndef()) {
@@ -11959,8 +11959,8 @@ fn zirShr(
const target = sema.mod.getTarget();
const scalar_ty = lhs_ty.scalarType();
- const maybe_lhs_val = try sema.resolveMaybeUndefVal(lhs);
- const maybe_rhs_val = try sema.resolveMaybeUndefVal(rhs);
+ const maybe_lhs_val = try sema.resolveMaybeUndefValIntable(lhs);
+ const maybe_rhs_val = try sema.resolveMaybeUndefValIntable(rhs);
const runtime_src = if (maybe_rhs_val) |rhs_val| rs: {
if (rhs_val.isUndef()) {
@@ -19697,7 +19697,7 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
}
}
- if (try sema.resolveMaybeUndefVal(operand)) |val| {
+ if (try sema.resolveMaybeUndefValIntable(operand)) |val| {
if (val.isUndef()) return sema.addConstUndef(dest_ty);
if (!is_vector) {
return sema.addConstant(
@@ -19901,7 +19901,7 @@ fn zirBitReverse(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
const operand = try sema.resolveInst(inst_data.operand);
const operand_ty = sema.typeOf(operand);
- _ = try sema.checkIntOrVectorAllowComptime(block, operand_ty, operand_src);
+ const scalar_ty = try sema.checkIntOrVector(block, operand, operand_src);
if (try sema.typeHasOnePossibleValue(operand_ty)) |val| {
return sema.addConstant(operand_ty, val);
@@ -19909,7 +19909,7 @@ fn zirBitReverse(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
const target = sema.mod.getTarget();
switch (operand_ty.zigTypeTag()) {
- .Int, .ComptimeInt => {
+ .Int => {
const runtime_src = if (try sema.resolveMaybeUndefVal(operand)) |val| {
if (val.isUndef()) return sema.addConstUndef(operand_ty);
const result_val = try val.bitReverse(operand_ty, target, sema.arena);
@@ -19929,7 +19929,7 @@ fn zirBitReverse(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
const elems = try sema.arena.alloc(Value, vec_len);
for (elems) |*elem, i| {
const elem_val = val.elemValueBuffer(sema.mod, i, &elem_buf);
- elem.* = try elem_val.bitReverse(operand_ty, target, sema.arena);
+ elem.* = try elem_val.bitReverse(scalar_ty, target, sema.arena);
}
return sema.addConstant(
operand_ty,
diff --git a/test/behavior.zig b/test/behavior.zig
index 51a261cc5c..4f8ad67203 100644
--- a/test/behavior.zig
+++ b/test/behavior.zig
@@ -106,7 +106,6 @@ test {
_ = @import("behavior/bugs/12430.zig");
_ = @import("behavior/bugs/12450.zig");
_ = @import("behavior/bugs/12486.zig");
- _ = @import("behavior/bugs/12488.zig");
_ = @import("behavior/bugs/12498.zig");
_ = @import("behavior/bugs/12551.zig");
_ = @import("behavior/bugs/12571.zig");
diff --git a/test/behavior/bugs/12488.zig b/test/behavior/bugs/12488.zig
deleted file mode 100644
index b05197b24f..0000000000
--- a/test/behavior/bugs/12488.zig
+++ /dev/null
@@ -1,13 +0,0 @@
-const expect = @import("std").testing.expect;
-
-const A = struct {
- a: u32,
-};
-
-fn foo(comptime a: anytype) !void {
- try expect(a[0][0] == @sizeOf(A));
-}
-
-test {
- try foo(.{[_]usize{@sizeOf(A)}});
-}
diff --git a/test/behavior/fn.zig b/test/behavior/fn.zig
index 8dca94a656..d5f959e507 100644
--- a/test/behavior/fn.zig
+++ b/test/behavior/fn.zig
@@ -517,3 +517,26 @@ test "peer type resolution of inferred error set with non-void payload" {
};
try expect(try S.openDataFile(.read) == 1);
}
+
+test "lazy values passed to anytype parameter" {
+ const A = struct {
+ a: u32,
+ fn foo(comptime a: anytype) !void {
+ try expect(a[0][0] == @sizeOf(@This()));
+ }
+ };
+ try A.foo(.{[_]usize{@sizeOf(A)}});
+
+ const B = struct {
+ fn foo(comptime a: anytype) !void {
+ try expect(a.x == 0);
+ }
+ };
+ try B.foo(.{ .x = @sizeOf(B) });
+
+ const C = struct {};
+ try expect(@truncate(u32, @sizeOf(C)) == 0);
+
+ const D = struct {};
+ try expect(@sizeOf(D) << 1 == 0);
+}