authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-06-28 20:50:14+03:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-06-30 09:57:38+02:00
logcc3336c7841c48622db855be95a79bbd030bade8
tree61e33f1add4655dcc28a25c239d5da27477be0e6
parent979910dc38cd15e506218d5175e5a91f56244055

Sema: add source location to coerce result ptr, fix negation error


12 files changed, 97 insertions(+), 69 deletions(-)

src/AstGen.zig+5-4
...@@ -1476,7 +1476,7 @@ fn arrayInitExprRlPtr(...@@ -1476,7 +1476,7 @@ fn arrayInitExprRlPtr(
1476 return arrayInitExprRlPtrInner(gz, scope, node, base_ptr, elements);1476 return arrayInitExprRlPtrInner(gz, scope, node, base_ptr, elements);
1477 }1477 }
14781478
1479 var as_scope = try gz.makeCoercionScope(scope, array_ty, result_ptr);1479 var as_scope = try gz.makeCoercionScope(scope, array_ty, result_ptr, node);
1480 defer as_scope.unstack();1480 defer as_scope.unstack();
14811481
1482 const result = try arrayInitExprRlPtrInner(&as_scope, scope, node, as_scope.rl_ptr, elements);1482 const result = try arrayInitExprRlPtrInner(&as_scope, scope, node, as_scope.rl_ptr, elements);
...@@ -1697,7 +1697,7 @@ fn structInitExprRlPtr(...@@ -1697,7 +1697,7 @@ fn structInitExprRlPtr(
1697 const ty_inst = try typeExpr(gz, scope, struct_init.ast.type_expr);1697 const ty_inst = try typeExpr(gz, scope, struct_init.ast.type_expr);
1698 _ = try gz.addUnNode(.validate_struct_init_ty, ty_inst, node);1698 _ = try gz.addUnNode(.validate_struct_init_ty, ty_inst, node);
16991699
1700 var as_scope = try gz.makeCoercionScope(scope, ty_inst, result_ptr);1700 var as_scope = try gz.makeCoercionScope(scope, ty_inst, result_ptr, node);
1701 defer as_scope.unstack();1701 defer as_scope.unstack();
17021702
1703 const result = try structInitExprRlPtrInner(&as_scope, scope, node, struct_init, as_scope.rl_ptr);1703 const result = try structInitExprRlPtrInner(&as_scope, scope, node, struct_init, as_scope.rl_ptr);
...@@ -7046,7 +7046,7 @@ fn asRlPtr(...@@ -7046,7 +7046,7 @@ fn asRlPtr(
7046 operand_node: Ast.Node.Index,7046 operand_node: Ast.Node.Index,
7047 dest_type: Zir.Inst.Ref,7047 dest_type: Zir.Inst.Ref,
7048) InnerError!Zir.Inst.Ref {7048) InnerError!Zir.Inst.Ref {
7049 var as_scope = try parent_gz.makeCoercionScope(scope, dest_type, result_ptr);7049 var as_scope = try parent_gz.makeCoercionScope(scope, dest_type, result_ptr, src_node);
7050 defer as_scope.unstack();7050 defer as_scope.unstack();
70517051
7052 const result = try reachableExpr(&as_scope, &as_scope.base, .{ .block_ptr = &as_scope }, operand_node, src_node);7052 const result = try reachableExpr(&as_scope, &as_scope.base, .{ .block_ptr = &as_scope }, operand_node, src_node);
...@@ -9903,13 +9903,14 @@ const GenZir = struct {...@@ -9903,13 +9903,14 @@ const GenZir = struct {
9903 scope: *Scope,9903 scope: *Scope,
9904 dest_type: Zir.Inst.Ref,9904 dest_type: Zir.Inst.Ref,
9905 result_ptr: Zir.Inst.Ref,9905 result_ptr: Zir.Inst.Ref,
9906 src_node: Ast.Node.Index,
9906 ) !GenZir {9907 ) !GenZir {
9907 // Detect whether this expr() call goes into rvalue() to store the result into the9908 // Detect whether this expr() call goes into rvalue() to store the result into the
9908 // result location. If it does, elide the coerce_result_ptr instruction9909 // result location. If it does, elide the coerce_result_ptr instruction
9909 // as well as the store instruction, instead passing the result as an rvalue.9910 // as well as the store instruction, instead passing the result as an rvalue.
9910 var as_scope = parent_gz.makeSubBlock(scope);9911 var as_scope = parent_gz.makeSubBlock(scope);
9911 errdefer as_scope.unstack();9912 errdefer as_scope.unstack();
9912 as_scope.rl_ptr = try as_scope.addBin(.coerce_result_ptr, dest_type, result_ptr);9913 as_scope.rl_ptr = try as_scope.addPlNode(.coerce_result_ptr, src_node, Zir.Inst.Bin{ .lhs = dest_type, .rhs = result_ptr });
99139914
9914 // `rl_ty_inst` needs to be set in case the stores to `rl_ptr` are eliminated.9915 // `rl_ty_inst` needs to be set in case the stores to `rl_ptr` are eliminated.
9915 as_scope.rl_ty_inst = dest_type;9916 as_scope.rl_ty_inst = dest_type;
src/Sema.zig+36-7
...@@ -1913,10 +1913,11 @@ fn zirCoerceResultPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE...@@ -1913,10 +1913,11 @@ fn zirCoerceResultPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE
1913 const tracy = trace(@src());1913 const tracy = trace(@src());
1914 defer tracy.end();1914 defer tracy.end();
19151915
1916 const src: LazySrcLoc = sema.src;1916 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
1917 const bin_inst = sema.code.instructions.items(.data)[inst].bin;1917 const src = inst_data.src();
1918 const pointee_ty = try sema.resolveType(block, src, bin_inst.lhs);1918 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
1919 const ptr = try sema.resolveInst(bin_inst.rhs);1919 const pointee_ty = try sema.resolveType(block, src, extra.lhs);
1920 const ptr = try sema.resolveInst(extra.rhs);
1920 const target = sema.mod.getTarget();1921 const target = sema.mod.getTarget();
1921 const addr_space = target_util.defaultAddressSpace(target, .local);1922 const addr_space = target_util.defaultAddressSpace(target, .local);
19221923
...@@ -10143,7 +10144,10 @@ fn zirNegate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -10143,7 +10144,10 @@ fn zirNegate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
10143 const rhs_ty = sema.typeOf(rhs);10144 const rhs_ty = sema.typeOf(rhs);
10144 const rhs_scalar_ty = rhs_ty.scalarType();10145 const rhs_scalar_ty = rhs_ty.scalarType();
1014510146
10146 if (rhs_scalar_ty.isUnsignedInt()) {10147 if (rhs_scalar_ty.isUnsignedInt() or switch (rhs_scalar_ty.zigTypeTag()) {
10148 .Int, .ComptimeInt, .Float, .ComptimeFloat => false,
10149 else => true,
10150 }) {
10147 return sema.fail(block, src, "negation of type '{}'", .{rhs_ty.fmt(sema.mod)});10151 return sema.fail(block, src, "negation of type '{}'", .{rhs_ty.fmt(sema.mod)});
10148 }10152 }
1014910153
...@@ -10172,6 +10176,12 @@ fn zirNegateWrap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!...@@ -10172,6 +10176,12 @@ fn zirNegateWrap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
1017210176
10173 const rhs = try sema.resolveInst(inst_data.operand);10177 const rhs = try sema.resolveInst(inst_data.operand);
10174 const rhs_ty = sema.typeOf(rhs);10178 const rhs_ty = sema.typeOf(rhs);
10179 const rhs_scalar_ty = rhs_ty.scalarType();
10180
10181 switch (rhs_scalar_ty.zigTypeTag()) {
10182 .Int, .ComptimeInt, .Float, .ComptimeFloat => {},
10183 else => return sema.fail(block, src, "negation of type '{}'", .{rhs_ty.fmt(sema.mod)}),
10184 }
1017510185
10176 const lhs = if (rhs_ty.zigTypeTag() == .Vector)10186 const lhs = if (rhs_ty.zigTypeTag() == .Vector)
10177 try sema.addConstant(rhs_ty, try Value.Tag.repeated.create(sema.arena, Value.zero))10187 try sema.addConstant(rhs_ty, try Value.Tag.repeated.create(sema.arena, Value.zero))
...@@ -17886,7 +17896,8 @@ fn validateRunTimeType(...@@ -17886,7 +17896,8 @@ fn validateRunTimeType(
17886 .Pointer => {17896 .Pointer => {
17887 const elem_ty = ty.childType();17897 const elem_ty = ty.childType();
17888 switch (elem_ty.zigTypeTag()) {17898 switch (elem_ty.zigTypeTag()) {
17889 .Opaque, .Fn => return true,17899 .Opaque => return true,
17900 .Fn => return elem_ty.isFnOrHasRuntimeBits(),
17890 else => ty = elem_ty,17901 else => ty = elem_ty,
17891 }17902 }
17892 },17903 },
...@@ -17950,7 +17961,25 @@ fn explainWhyTypeIsComptime(...@@ -17950,7 +17961,25 @@ fn explainWhyTypeIsComptime(
17950 .Optional,17961 .Optional,
17951 => return,17962 => return,
1795217963
17953 .Pointer, .Array, .Vector => {17964 .Array, .Vector => {
17965 try sema.explainWhyTypeIsComptime(block, src, msg, src_loc, ty.elemType());
17966 },
17967 .Pointer => {
17968 const elem_ty = ty.elemType2();
17969 if (elem_ty.zigTypeTag() == .Fn) {
17970 const fn_info = elem_ty.fnInfo();
17971 if (fn_info.is_generic) {
17972 try mod.errNoteNonLazy(src_loc, msg, "function is generic", .{});
17973 }
17974 switch (fn_info.cc) {
17975 .Inline => try mod.errNoteNonLazy(src_loc, msg, "function has inline calling convention", .{}),
17976 else => {},
17977 }
17978 if (fn_info.return_type.comptimeOnly()) {
17979 try mod.errNoteNonLazy(src_loc, msg, "function has a comptime-only return type", .{});
17980 }
17981 return;
17982 }
17954 try sema.explainWhyTypeIsComptime(block, src, msg, src_loc, ty.elemType());17983 try sema.explainWhyTypeIsComptime(block, src, msg, src_loc, ty.elemType());
17955 },17984 },
1795617985
src/Zir.zig+2-2
...@@ -308,7 +308,7 @@ pub const Inst = struct {...@@ -308,7 +308,7 @@ pub const Inst = struct {
308 cmp_neq,308 cmp_neq,
309 /// Coerces a result location pointer to a new element type. It is evaluated "backwards"-309 /// Coerces a result location pointer to a new element type. It is evaluated "backwards"-
310 /// as type coercion from the new element type to the old element type.310 /// as type coercion from the new element type to the old element type.
311 /// Uses the `bin` union field.311 /// Uses the `pl_node` union field. Payload is `Bin`.
312 /// LHS is destination element type, RHS is result pointer.312 /// LHS is destination element type, RHS is result pointer.
313 coerce_result_ptr,313 coerce_result_ptr,
314 /// Conditional branch. Splits control flow based on a boolean condition value.314 /// Conditional branch. Splits control flow based on a boolean condition value.
...@@ -1603,7 +1603,7 @@ pub const Inst = struct {...@@ -1603,7 +1603,7 @@ pub const Inst = struct {
1603 .cmp_gte = .pl_node,1603 .cmp_gte = .pl_node,
1604 .cmp_gt = .pl_node,1604 .cmp_gt = .pl_node,
1605 .cmp_neq = .pl_node,1605 .cmp_neq = .pl_node,
1606 .coerce_result_ptr = .bin,1606 .coerce_result_ptr = .pl_node,
1607 .condbr = .pl_node,1607 .condbr = .pl_node,
1608 .condbr_inline = .pl_node,1608 .condbr_inline = .pl_node,
1609 .@"try" = .pl_node,1609 .@"try" = .pl_node,
src/print_zir.zig+1-1
...@@ -144,7 +144,6 @@ const Writer = struct {...@@ -144,7 +144,6 @@ const Writer = struct {
144 switch (tag) {144 switch (tag) {
145 .array_type,145 .array_type,
146 .as,146 .as,
147 .coerce_result_ptr,
148 .elem_ptr,147 .elem_ptr,
149 .elem_val,148 .elem_val,
150 .store,149 .store,
...@@ -355,6 +354,7 @@ const Writer = struct {...@@ -355,6 +354,7 @@ const Writer = struct {
355 .minimum,354 .minimum,
356 .elem_ptr_node,355 .elem_ptr_node,
357 .elem_val_node,356 .elem_val_node,
357 .coerce_result_ptr,
358 => try self.writePlNodeBin(stream, inst),358 => try self.writePlNodeBin(stream, inst),
359359
360 .elem_ptr_imm => try self.writeElemPtrImm(stream, inst),360 .elem_ptr_imm => try self.writeElemPtrImm(stream, inst),
test/cases/compile_errors/assign_inline_fn_to_non-comptime_var.zig created+12
...@@ -0,0 +1,12 @@
1export fn entry() void {
2 var a = &b;
3 _ = a;
4}
5fn b() callconv(.Inline) void { }
6
7// error
8// backend=stage2
9// target=native
10//
11// :2:9: error: variable of type '*const fn() callconv(.Inline) void' must be const or comptime
12// :2:9: note: function has inline calling convention
test/cases/compile_errors/attempt_to_negate_a_non-integer_non-float_or_non-vector_type.zig created+14
...@@ -0,0 +1,14 @@
1fn foo() anyerror!u32 {
2 return 1;
3}
4
5export fn entry() void {
6 const x = -foo();
7 _ = x;
8}
9
10// error
11// backend=stage2
12// target=native
13//
14// :6:15: error: negation of type 'anyerror!u32'
test/cases/compile_errors/reassign_to_array_parameter.zig created+12
...@@ -0,0 +1,12 @@
1fn reassign(a: [3]f32) void {
2 a = [3]f32{4, 5, 6};
3}
4export fn entry() void {
5 reassign(.{1, 2, 3});
6}
7
8// error
9// backend=stage2
10// target=native
11//
12// :2:15: error: cannot assign to constant
test/cases/compile_errors/reassign_to_struct_parameter.zig created+15
...@@ -0,0 +1,15 @@
1const S = struct {
2 x: u32,
3};
4fn reassign(s: S) void {
5 s = S{.x = 2};
6}
7export fn entry() void {
8 reassign(S{.x = 3});
9}
10
11// error
12// backend=stage2
13// target=native
14//
15// :5:10: error: cannot assign to constant
test/cases/compile_errors/stage1/obj/assign_inline_fn_to_non-comptime_var.zig deleted-12
...@@ -1,12 +0,0 @@
1export fn entry() void {
2 var a = b;
3 _ = a;
4}
5fn b() callconv(.Inline) void { }
6
7// error
8// backend=stage1
9// target=native
10//
11// tmp.zig:2:5: error: functions marked inline must be stored in const or comptime var
12// tmp.zig:5:1: note: declared here
test/cases/compile_errors/stage1/obj/attempt_to_negate_a_non-integer_non-float_or_non-vector_type.zig deleted-14
...@@ -1,14 +0,0 @@
1fn foo() anyerror!u32 {
2 return 1;
3}
4
5export fn entry() void {
6 const x = -foo();
7 _ = x;
8}
9
10// error
11// backend=stage1
12// target=native
13//
14// tmp.zig:6:15: error: negation of type 'anyerror!u32'
test/cases/compile_errors/stage1/test/reassign_to_array_parameter.zig deleted-13
...@@ -1,13 +0,0 @@
1fn reassign(a: [3]f32) void {
2 a = [3]f32{4, 5, 6};
3}
4export fn entry() void {
5 reassign(.{1, 2, 3});
6}
7
8// error
9// backend=stage1
10// target=native
11// is_test=1
12//
13// tmp.zig:2:15: error: cannot assign to constant
test/cases/compile_errors/stage1/test/reassign_to_struct_parameter.zig deleted-16
...@@ -1,16 +0,0 @@
1const S = struct {
2 x: u32,
3};
4fn reassign(s: S) void {
5 s = S{.x = 2};
6}
7export fn entry() void {
8 reassign(S{.x = 3});
9}
10
11// error
12// backend=stage1
13// target=native
14// is_test=1
15//
16// tmp.zig:5:10: error: cannot assign to constant