authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2023-01-18 12:56:48+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2023-01-22 00:12:36+02:00
logd284c00fda45b943f4ed5244ae1cb9e7f90f481f
treebfec199eade94e25e173b0150b565bd1123f7764
parent7f635ae7bdf63da19d09763c7fdbdc61fa035282

Sema: handle lazy values in more places

* resolve lazy values in anon structs being passed to anytype params * use `resolveMaybeUndefValIntable` where appropriate Closes #14356

4 files changed, 32 insertions(+), 23 deletions(-)

src/Sema.zig+9-9
...@@ -7514,7 +7514,7 @@ fn resolveGenericInstantiationType(...@@ -7514,7 +7514,7 @@ fn resolveGenericInstantiationType(
7514}7514}
75157515
7516fn resolveTupleLazyValues(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError!void {7516fn resolveTupleLazyValues(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError!void {
7517 if (!ty.isSimpleTuple()) return;7517 if (!ty.isSimpleTupleOrAnonStruct()) return;
7518 const tuple = ty.tupleFields();7518 const tuple = ty.tupleFields();
7519 for (tuple.values) |field_val, i| {7519 for (tuple.values) |field_val, i| {
7520 try sema.resolveTupleLazyValues(block, src, tuple.types[i]);7520 try sema.resolveTupleLazyValues(block, src, tuple.types[i]);
...@@ -11771,8 +11771,8 @@ fn zirShl(...@@ -11771,8 +11771,8 @@ fn zirShl(
11771 // TODO coerce rhs if air_tag is not shl_sat11771 // TODO coerce rhs if air_tag is not shl_sat
11772 const rhs_is_comptime_int = try sema.checkIntType(block, rhs_src, scalar_rhs_ty);11772 const rhs_is_comptime_int = try sema.checkIntType(block, rhs_src, scalar_rhs_ty);
1177311773
11774 const maybe_lhs_val = try sema.resolveMaybeUndefVal(lhs);11774 const maybe_lhs_val = try sema.resolveMaybeUndefValIntable(lhs);
11775 const maybe_rhs_val = try sema.resolveMaybeUndefVal(rhs);11775 const maybe_rhs_val = try sema.resolveMaybeUndefValIntable(rhs);
1177611776
11777 if (maybe_rhs_val) |rhs_val| {11777 if (maybe_rhs_val) |rhs_val| {
11778 if (rhs_val.isUndef()) {11778 if (rhs_val.isUndef()) {
...@@ -11959,8 +11959,8 @@ fn zirShr(...@@ -11959,8 +11959,8 @@ fn zirShr(
11959 const target = sema.mod.getTarget();11959 const target = sema.mod.getTarget();
11960 const scalar_ty = lhs_ty.scalarType();11960 const scalar_ty = lhs_ty.scalarType();
1196111961
11962 const maybe_lhs_val = try sema.resolveMaybeUndefVal(lhs);11962 const maybe_lhs_val = try sema.resolveMaybeUndefValIntable(lhs);
11963 const maybe_rhs_val = try sema.resolveMaybeUndefVal(rhs);11963 const maybe_rhs_val = try sema.resolveMaybeUndefValIntable(rhs);
1196411964
11965 const runtime_src = if (maybe_rhs_val) |rhs_val| rs: {11965 const runtime_src = if (maybe_rhs_val) |rhs_val| rs: {
11966 if (rhs_val.isUndef()) {11966 if (rhs_val.isUndef()) {
...@@ -19697,7 +19697,7 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -19697,7 +19697,7 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
19697 }19697 }
19698 }19698 }
1969919699
19700 if (try sema.resolveMaybeUndefVal(operand)) |val| {19700 if (try sema.resolveMaybeUndefValIntable(operand)) |val| {
19701 if (val.isUndef()) return sema.addConstUndef(dest_ty);19701 if (val.isUndef()) return sema.addConstUndef(dest_ty);
19702 if (!is_vector) {19702 if (!is_vector) {
19703 return sema.addConstant(19703 return sema.addConstant(
...@@ -19901,7 +19901,7 @@ fn zirBitReverse(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!...@@ -19901,7 +19901,7 @@ fn zirBitReverse(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
19901 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };19901 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
19902 const operand = try sema.resolveInst(inst_data.operand);19902 const operand = try sema.resolveInst(inst_data.operand);
19903 const operand_ty = sema.typeOf(operand);19903 const operand_ty = sema.typeOf(operand);
19904 _ = try sema.checkIntOrVectorAllowComptime(block, operand_ty, operand_src);19904 const scalar_ty = try sema.checkIntOrVector(block, operand, operand_src);
1990519905
19906 if (try sema.typeHasOnePossibleValue(operand_ty)) |val| {19906 if (try sema.typeHasOnePossibleValue(operand_ty)) |val| {
19907 return sema.addConstant(operand_ty, val);19907 return sema.addConstant(operand_ty, val);
...@@ -19909,7 +19909,7 @@ fn zirBitReverse(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!...@@ -19909,7 +19909,7 @@ fn zirBitReverse(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
1990919909
19910 const target = sema.mod.getTarget();19910 const target = sema.mod.getTarget();
19911 switch (operand_ty.zigTypeTag()) {19911 switch (operand_ty.zigTypeTag()) {
19912 .Int, .ComptimeInt => {19912 .Int => {
19913 const runtime_src = if (try sema.resolveMaybeUndefVal(operand)) |val| {19913 const runtime_src = if (try sema.resolveMaybeUndefVal(operand)) |val| {
19914 if (val.isUndef()) return sema.addConstUndef(operand_ty);19914 if (val.isUndef()) return sema.addConstUndef(operand_ty);
19915 const result_val = try val.bitReverse(operand_ty, target, sema.arena);19915 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!...@@ -19929,7 +19929,7 @@ fn zirBitReverse(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
19929 const elems = try sema.arena.alloc(Value, vec_len);19929 const elems = try sema.arena.alloc(Value, vec_len);
19930 for (elems) |*elem, i| {19930 for (elems) |*elem, i| {
19931 const elem_val = val.elemValueBuffer(sema.mod, i, &elem_buf);19931 const elem_val = val.elemValueBuffer(sema.mod, i, &elem_buf);
19932 elem.* = try elem_val.bitReverse(operand_ty, target, sema.arena);19932 elem.* = try elem_val.bitReverse(scalar_ty, target, sema.arena);
19933 }19933 }
19934 return sema.addConstant(19934 return sema.addConstant(
19935 operand_ty,19935 operand_ty,
test/behavior.zig-1
...@@ -106,7 +106,6 @@ test {...@@ -106,7 +106,6 @@ test {
106 _ = @import("behavior/bugs/12430.zig");106 _ = @import("behavior/bugs/12430.zig");
107 _ = @import("behavior/bugs/12450.zig");107 _ = @import("behavior/bugs/12450.zig");
108 _ = @import("behavior/bugs/12486.zig");108 _ = @import("behavior/bugs/12486.zig");
109 _ = @import("behavior/bugs/12488.zig");
110 _ = @import("behavior/bugs/12498.zig");109 _ = @import("behavior/bugs/12498.zig");
111 _ = @import("behavior/bugs/12551.zig");110 _ = @import("behavior/bugs/12551.zig");
112 _ = @import("behavior/bugs/12571.zig");111 _ = @import("behavior/bugs/12571.zig");
test/behavior/bugs/12488.zig deleted-13
...@@ -1,13 +0,0 @@
1const expect = @import("std").testing.expect;
2
3const A = struct {
4 a: u32,
5};
6
7fn foo(comptime a: anytype) !void {
8 try expect(a[0][0] == @sizeOf(A));
9}
10
11test {
12 try foo(.{[_]usize{@sizeOf(A)}});
13}
test/behavior/fn.zig+23
...@@ -517,3 +517,26 @@ test "peer type resolution of inferred error set with non-void payload" {...@@ -517,3 +517,26 @@ test "peer type resolution of inferred error set with non-void payload" {
517 };517 };
518 try expect(try S.openDataFile(.read) == 1);518 try expect(try S.openDataFile(.read) == 1);
519}519}
520
521test "lazy values passed to anytype parameter" {
522 const A = struct {
523 a: u32,
524 fn foo(comptime a: anytype) !void {
525 try expect(a[0][0] == @sizeOf(@This()));
526 }
527 };
528 try A.foo(.{[_]usize{@sizeOf(A)}});
529
530 const B = struct {
531 fn foo(comptime a: anytype) !void {
532 try expect(a.x == 0);
533 }
534 };
535 try B.foo(.{ .x = @sizeOf(B) });
536
537 const C = struct {};
538 try expect(@truncate(u32, @sizeOf(C)) == 0);
539
540 const D = struct {};
541 try expect(@sizeOf(D) << 1 == 0);
542}