authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-08-12 10:45:37-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-08-12 10:48:54-07:00
log55c6a784a5bdf37c90cc9d8f55e9a86d396b8af4
tree617bd6b751f54fb946c4233b48d3fac0867674b9
parentfc55814faa8970cc373b7bbf8479c3bc3934fb44

stage2 frontend improvements - `@ptrCast` and optionals

* AstGen: use coerced_ty ResultLoc on array types and rely on Sema doing type coercion, to reduce the size of the ZIR for these instructions. * Sema: implement `@ptrCast`. * Sema: implement coercion from `T` to `?T` with an intermediate coercion rather than equality check.

2 files changed, 32 insertions(+), 15 deletions(-)

src/AstGen.zig+3-3
......@@ -2791,7 +2791,7 @@ fn arrayType(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) !Z
27912791 {
27922792 return astgen.failNode(len_node, "unable to infer array size", .{});
27932793 }
2794 const len = try expr(gz, scope, .{ .ty = .usize_type }, len_node);
2794 const len = try expr(gz, scope, .{ .coerced_ty = .usize_type }, len_node);
27952795 const elem_type = try typeExpr(gz, scope, node_datas[node].rhs);
27962796
27972797 const result = try gz.addBin(.array_type, len, elem_type);
......@@ -2812,9 +2812,9 @@ fn arrayTypeSentinel(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.I
28122812 {
28132813 return astgen.failNode(len_node, "unable to infer array size", .{});
28142814 }
2815 const len = try expr(gz, scope, .{ .ty = .usize_type }, len_node);
2815 const len = try expr(gz, scope, .{ .coerced_ty = .usize_type }, len_node);
28162816 const elem_type = try typeExpr(gz, scope, extra.elem_type);
2817 const sentinel = try expr(gz, scope, .{ .ty = elem_type }, extra.sentinel);
2817 const sentinel = try expr(gz, scope, .{ .coerced_ty = elem_type }, extra.sentinel);
28182818
28192819 const result = try gz.addArrayTypeSentinel(len, elem_type, sentinel);
28202820 return rvalue(gz, rl, result, node);
src/Sema.zig+29-12
......@@ -3026,9 +3026,9 @@ fn zirArrayType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileE
30263026 defer tracy.end();
30273027
30283028 const bin_inst = sema.code.instructions.items(.data)[inst].bin;
3029 const len = try sema.resolveInstConst(block, .unneeded, bin_inst.lhs);
3029 const len = try sema.resolveInt(block, .unneeded, bin_inst.lhs, Type.initTag(.usize));
30303030 const elem_type = try sema.resolveType(block, .unneeded, bin_inst.rhs);
3031 const array_ty = try Module.arrayType(sema.arena, len.val.toUnsignedInt(), null, elem_type);
3031 const array_ty = try Module.arrayType(sema.arena, len, null, elem_type);
30323032
30333033 return sema.addType(array_ty);
30343034}
......@@ -3038,11 +3038,13 @@ fn zirArrayTypeSentinel(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index)
30383038 defer tracy.end();
30393039
30403040 const inst_data = sema.code.instructions.items(.data)[inst].array_type_sentinel;
3041 const len = try sema.resolveInstConst(block, .unneeded, inst_data.len);
3041 const len = try sema.resolveInt(block, .unneeded, inst_data.len, Type.initTag(.usize));
30423042 const extra = sema.code.extraData(Zir.Inst.ArrayTypeSentinel, inst_data.payload_index).data;
3043 const sentinel = try sema.resolveInstConst(block, .unneeded, extra.sentinel);
30443043 const elem_type = try sema.resolveType(block, .unneeded, extra.elem_type);
3045 const array_ty = try Module.arrayType(sema.arena, len.val.toUnsignedInt(), sentinel.val, elem_type);
3044 const uncasted_sentinel = sema.resolveInst(extra.sentinel);
3045 const sentinel = try sema.coerce(block, elem_type, uncasted_sentinel, .unneeded);
3046 const sentinel_val = try sema.resolveConstValue(block, .unneeded, sentinel);
3047 const array_ty = try Module.arrayType(sema.arena, len, sentinel_val, elem_type);
30463048
30473049 return sema.addType(array_ty);
30483050}
......@@ -6774,8 +6776,26 @@ fn zirErrSetCast(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Compile
67746776
67756777fn zirPtrCast(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
67766778 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
6777 const src = inst_data.src();
6778 return sema.mod.fail(&block.base, src, "TODO: Sema.zirPtrCast", .{});
6779 const dest_ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
6780 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };
6781 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
6782 const dest_ty = try sema.resolveType(block, dest_ty_src, extra.lhs);
6783 const operand = sema.resolveInst(extra.rhs);
6784 const operand_ty = sema.typeOf(operand);
6785 if (operand_ty.zigTypeTag() != .Pointer) {
6786 return sema.mod.fail(&block.base, operand_src, "expected pointer, found {s} type '{}'", .{
6787 @tagName(operand_ty.zigTypeTag()), operand_ty,
6788 });
6789 }
6790 if (dest_ty.zigTypeTag() != .Pointer) {
6791 return sema.mod.fail(&block.base, dest_ty_src, "expected pointer, found {s} type '{}'", .{
6792 @tagName(dest_ty.zigTypeTag()), dest_ty,
6793 });
6794 }
6795 if (try sema.resolveMaybeUndefVal(block, operand_src, operand)) |val| {
6796 return sema.addConstant(dest_ty, val);
6797 }
6798 return block.addTyOp(.bitcast, dest_ty, operand);
67796799}
67806800
67816801fn zirTruncate(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
......@@ -8151,11 +8171,8 @@ fn coerce(
81518171 // T to ?T
81528172 var buf: Type.Payload.ElemType = undefined;
81538173 const child_type = dest_type.optionalChild(&buf);
8154 if (child_type.eql(inst_ty)) {
8155 return sema.wrapOptional(block, dest_type, inst, inst_src);
8156 } else if (try sema.coerceNum(block, child_type, inst, inst_src)) |some| {
8157 return sema.wrapOptional(block, dest_type, some, inst_src);
8158 }
8174 const intermediate = try sema.coerce(block, child_type, inst, inst_src);
8175 return sema.wrapOptional(block, dest_type, intermediate, inst_src);
81598176 },
81608177 .Pointer => {
81618178 // Coercions where the source is a single pointer to an array.