mirror of
https://github.com/ziglang/zig.git
synced 2025-12-29 09:33:18 +00:00
AstGen: migrate ty result locations to coerced_ty
In most cases where AstGen is coercing to a fixed type (such as `u29`, `type`, `std.builtin.CallingConvention) we do not necessarily require an explicit coercion instruction. Instead, Sema knows the type that is required, and can perform the coercion after the fact. This means we can use the `coerced_ty` result location kind, saving unnecessary coercion instructions and therefore ZIR bytes. This required a few enhancements to Sema to introduce missing coercions.
This commit is contained in:
parent
434537213e
commit
10784c7fc8
117
src/AstGen.zig
117
src/AstGen.zig
@ -360,16 +360,11 @@ const ResultInfo = struct {
|
||||
};
|
||||
};
|
||||
|
||||
/// TODO: modify Sema to remove in favour of `coerced_align_ri`
|
||||
const align_ri: ResultInfo = .{ .rl = .{ .ty = .u29_type } };
|
||||
const coerced_align_ri: ResultInfo = .{ .rl = .{ .coerced_ty = .u29_type } };
|
||||
/// TODO: modify Sema to remove in favour of `coerced_addrspace_ri`
|
||||
const addrspace_ri: ResultInfo = .{ .rl = .{ .ty = .address_space_type } };
|
||||
const coerced_addrspace_ri: ResultInfo = .{ .rl = .{ .coerced_ty = .address_space_type } };
|
||||
const coerced_linksection_ri: ResultInfo = .{ .rl = .{ .coerced_ty = .slice_const_u8_type } };
|
||||
const bool_ri: ResultInfo = .{ .rl = .{ .ty = .bool_type } };
|
||||
const type_ri: ResultInfo = .{ .rl = .{ .ty = .type_type } };
|
||||
const coerced_type_ri: ResultInfo = .{ .rl = .{ .coerced_ty = .type_type } };
|
||||
const coerced_bool_ri: ResultInfo = .{ .rl = .{ .coerced_ty = .bool_type } };
|
||||
|
||||
fn typeExpr(gz: *GenZir, scope: *Scope, type_node: Ast.Node.Index) InnerError!Zir.Inst.Ref {
|
||||
return comptimeExpr(gz, scope, coerced_type_ri, type_node);
|
||||
@ -786,7 +781,7 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE
|
||||
.bool_and => return boolBinOp(gz, scope, ri, node, .bool_br_and),
|
||||
.bool_or => return boolBinOp(gz, scope, ri, node, .bool_br_or),
|
||||
|
||||
.bool_not => return simpleUnOp(gz, scope, ri, node, bool_ri, node_datas[node].lhs, .bool_not),
|
||||
.bool_not => return simpleUnOp(gz, scope, ri, node, coerced_bool_ri, node_datas[node].lhs, .bool_not),
|
||||
.bit_not => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, node_datas[node].lhs, .bit_not),
|
||||
|
||||
.negation => return negation(gz, scope, ri, node),
|
||||
@ -1372,7 +1367,7 @@ fn fnProtoExpr(
|
||||
};
|
||||
|
||||
const align_ref: Zir.Inst.Ref = if (fn_proto.ast.align_expr == 0) .none else inst: {
|
||||
break :inst try expr(&block_scope, scope, align_ri, fn_proto.ast.align_expr);
|
||||
break :inst try expr(&block_scope, scope, coerced_align_ri, fn_proto.ast.align_expr);
|
||||
};
|
||||
|
||||
if (fn_proto.ast.addrspace_expr != 0) {
|
||||
@ -1387,7 +1382,7 @@ fn fnProtoExpr(
|
||||
try expr(
|
||||
&block_scope,
|
||||
scope,
|
||||
.{ .rl = .{ .ty = .calling_convention_type } },
|
||||
.{ .rl = .{ .coerced_ty = .calling_convention_type } },
|
||||
fn_proto.ast.callconv_expr,
|
||||
)
|
||||
else
|
||||
@ -3136,7 +3131,7 @@ fn varDecl(
|
||||
}
|
||||
|
||||
const align_inst: Zir.Inst.Ref = if (var_decl.ast.align_node != 0)
|
||||
try expr(gz, scope, align_ri, var_decl.ast.align_node)
|
||||
try expr(gz, scope, coerced_align_ri, var_decl.ast.align_node)
|
||||
else
|
||||
.none;
|
||||
|
||||
@ -3505,7 +3500,7 @@ fn assignDestructureMaybeDecls(
|
||||
const this_lhs_comptime = is_comptime or (is_const and rhs_is_comptime);
|
||||
|
||||
const align_inst: Zir.Inst.Ref = if (full.ast.align_node != 0)
|
||||
try expr(gz, scope, align_ri, full.ast.align_node)
|
||||
try expr(gz, scope, coerced_align_ri, full.ast.align_node)
|
||||
else
|
||||
.none;
|
||||
|
||||
@ -3783,7 +3778,7 @@ fn ptrType(
|
||||
gz.astgen.source_line = source_line;
|
||||
gz.astgen.source_column = source_column;
|
||||
|
||||
addrspace_ref = try expr(gz, scope, addrspace_ri, ptr_info.ast.addrspace_node);
|
||||
addrspace_ref = try expr(gz, scope, coerced_addrspace_ri, ptr_info.ast.addrspace_node);
|
||||
trailing_count += 1;
|
||||
}
|
||||
if (ptr_info.ast.align_node != 0) {
|
||||
@ -4176,7 +4171,7 @@ fn fnDecl(
|
||||
var addrspace_gz = decl_gz.makeSubBlock(params_scope);
|
||||
defer addrspace_gz.unstack();
|
||||
const addrspace_ref: Zir.Inst.Ref = if (fn_proto.ast.addrspace_expr == 0) .none else inst: {
|
||||
const inst = try expr(&decl_gz, params_scope, addrspace_ri, fn_proto.ast.addrspace_expr);
|
||||
const inst = try expr(&decl_gz, params_scope, coerced_addrspace_ri, fn_proto.ast.addrspace_expr);
|
||||
if (addrspace_gz.instructionsSlice().len == 0) {
|
||||
// In this case we will send a len=0 body which can be encoded more efficiently.
|
||||
break :inst inst;
|
||||
@ -4431,7 +4426,7 @@ fn globalVarDecl(
|
||||
try expr(
|
||||
&block_scope,
|
||||
&block_scope.base,
|
||||
.{ .rl = .{ .ty = .type_type } },
|
||||
coerced_type_ri,
|
||||
var_decl.ast.type_node,
|
||||
)
|
||||
else
|
||||
@ -5254,7 +5249,7 @@ fn unionDeclInner(
|
||||
return astgen.failNode(member_node, "union field missing type", .{});
|
||||
}
|
||||
if (have_align) {
|
||||
const align_inst = try expr(&block_scope, &block_scope.base, .{ .rl = .{ .ty = .u32_type } }, member.ast.align_expr);
|
||||
const align_inst = try expr(&block_scope, &block_scope.base, coerced_align_ri, member.ast.align_expr);
|
||||
wip_members.appendToField(@intFromEnum(align_inst));
|
||||
any_aligned_fields = true;
|
||||
}
|
||||
@ -5522,7 +5517,7 @@ fn containerDecl(
|
||||
namespace.base.tag = .enum_namespace;
|
||||
|
||||
const arg_inst: Zir.Inst.Ref = if (container_decl.ast.arg != 0)
|
||||
try comptimeExpr(&block_scope, &namespace.base, .{ .rl = .{ .ty = .type_type } }, container_decl.ast.arg)
|
||||
try comptimeExpr(&block_scope, &namespace.base, coerced_type_ri, container_decl.ast.arg)
|
||||
else
|
||||
.none;
|
||||
|
||||
@ -6079,7 +6074,7 @@ fn arrayAccess(
|
||||
|
||||
const cursor = maybeAdvanceSourceCursorToMainToken(gz, node);
|
||||
|
||||
const rhs = try expr(gz, scope, .{ .rl = .{ .ty = .usize_type } }, node_datas[node].rhs);
|
||||
const rhs = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .usize_type } }, node_datas[node].rhs);
|
||||
try emitDbgStmt(gz, cursor);
|
||||
|
||||
return gz.addPlNode(.elem_ptr_node, node, Zir.Inst.Bin{ .lhs = lhs, .rhs = rhs });
|
||||
@ -6089,7 +6084,7 @@ fn arrayAccess(
|
||||
|
||||
const cursor = maybeAdvanceSourceCursorToMainToken(gz, node);
|
||||
|
||||
const rhs = try expr(gz, scope, .{ .rl = .{ .ty = .usize_type } }, node_datas[node].rhs);
|
||||
const rhs = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .usize_type } }, node_datas[node].rhs);
|
||||
try emitDbgStmt(gz, cursor);
|
||||
|
||||
return rvalue(gz, ri, try gz.addPlNode(.elem_val_node, node, Zir.Inst.Bin{ .lhs = lhs, .rhs = rhs }), node);
|
||||
@ -6157,12 +6152,12 @@ fn boolBinOp(
|
||||
const tree = astgen.tree;
|
||||
const node_datas = tree.nodes.items(.data);
|
||||
|
||||
const lhs = try expr(gz, scope, bool_ri, node_datas[node].lhs);
|
||||
const lhs = try expr(gz, scope, coerced_bool_ri, node_datas[node].lhs);
|
||||
const bool_br = (try gz.addPlNodePayloadIndex(zir_tag, node, undefined)).toIndex().?;
|
||||
|
||||
var rhs_scope = gz.makeSubBlock(scope);
|
||||
defer rhs_scope.unstack();
|
||||
const rhs = try expr(&rhs_scope, &rhs_scope.base, bool_ri, node_datas[node].rhs);
|
||||
const rhs = try expr(&rhs_scope, &rhs_scope.base, coerced_bool_ri, node_datas[node].rhs);
|
||||
if (!gz.refIsNoReturn(rhs)) {
|
||||
_ = try rhs_scope.addBreakWithSrcNode(.break_inline, bool_br, rhs, node_datas[node].rhs);
|
||||
}
|
||||
@ -6230,7 +6225,7 @@ fn ifExpr(
|
||||
.bool_bit = try block_scope.addUnNode(tag, optional, if_full.ast.cond_expr),
|
||||
};
|
||||
} else {
|
||||
const cond = try expr(&block_scope, &block_scope.base, bool_ri, if_full.ast.cond_expr);
|
||||
const cond = try expr(&block_scope, &block_scope.base, coerced_bool_ri, if_full.ast.cond_expr);
|
||||
break :c .{
|
||||
.inst = cond,
|
||||
.bool_bit = cond,
|
||||
@ -6476,7 +6471,7 @@ fn whileExpr(
|
||||
.bool_bit = try cond_scope.addUnNode(tag, optional, while_full.ast.cond_expr),
|
||||
};
|
||||
} else {
|
||||
const cond = try expr(&cond_scope, &cond_scope.base, bool_ri, while_full.ast.cond_expr);
|
||||
const cond = try expr(&cond_scope, &cond_scope.base, coerced_bool_ri, while_full.ast.cond_expr);
|
||||
break :c .{
|
||||
.inst = cond,
|
||||
.bool_bit = cond,
|
||||
@ -8052,7 +8047,7 @@ fn ret(gz: *GenZir, scope: *Scope, node: Ast.Node.Index) InnerError!Zir.Inst.Ref
|
||||
.rl = .{ .ptr = .{ .inst = try gz.addNode(.ret_ptr, node) } },
|
||||
.ctx = .@"return",
|
||||
} else .{
|
||||
.rl = .{ .ty = astgen.fn_ret_ty },
|
||||
.rl = .{ .coerced_ty = astgen.fn_ret_ty },
|
||||
.ctx = .@"return",
|
||||
};
|
||||
const prev_anon_name_strategy = gz.anon_name_strategy;
|
||||
@ -8688,7 +8683,7 @@ fn unionInit(
|
||||
params: []const Ast.Node.Index,
|
||||
) InnerError!Zir.Inst.Ref {
|
||||
const union_type = try typeExpr(gz, scope, params[0]);
|
||||
const field_name = try comptimeExpr(gz, scope, .{ .rl = .{ .ty = .slice_const_u8_type } }, params[1]);
|
||||
const field_name = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = .slice_const_u8_type } }, params[1]);
|
||||
const field_type = try gz.addPlNode(.field_type_ref, node, Zir.Inst.FieldTypeRef{
|
||||
.container_type = union_type,
|
||||
.field_name = field_name,
|
||||
@ -9001,12 +8996,12 @@ fn builtinCall(
|
||||
if (ri.rl == .ref or ri.rl == .ref_coerced_ty) {
|
||||
return gz.addPlNode(.field_ptr_named, node, Zir.Inst.FieldNamed{
|
||||
.lhs = try expr(gz, scope, .{ .rl = .ref }, params[0]),
|
||||
.field_name = try comptimeExpr(gz, scope, .{ .rl = .{ .ty = .slice_const_u8_type } }, params[1]),
|
||||
.field_name = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = .slice_const_u8_type } }, params[1]),
|
||||
});
|
||||
}
|
||||
const result = try gz.addPlNode(.field_val_named, node, Zir.Inst.FieldNamed{
|
||||
.lhs = try expr(gz, scope, .{ .rl = .none }, params[0]),
|
||||
.field_name = try comptimeExpr(gz, scope, .{ .rl = .{ .ty = .slice_const_u8_type } }, params[1]),
|
||||
.field_name = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = .slice_const_u8_type } }, params[1]),
|
||||
});
|
||||
return rvalue(gz, ri, result, node);
|
||||
},
|
||||
@ -9133,7 +9128,7 @@ fn builtinCall(
|
||||
return rvalue(gz, ri, .void_value, node);
|
||||
},
|
||||
.set_align_stack => {
|
||||
const order = try expr(gz, scope, align_ri, params[0]);
|
||||
const order = try expr(gz, scope, coerced_align_ri, params[0]);
|
||||
_ = try gz.addExtendedPayload(.set_align_stack, Zir.Inst.UnNode{
|
||||
.node = gz.nodeIndexToRelative(node),
|
||||
.operand = order,
|
||||
@ -9175,32 +9170,32 @@ fn builtinCall(
|
||||
.bit_size_of => return simpleUnOpType(gz, scope, ri, node, params[0], .bit_size_of),
|
||||
.align_of => return simpleUnOpType(gz, scope, ri, node, params[0], .align_of),
|
||||
|
||||
.int_from_ptr => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, params[0], .int_from_ptr),
|
||||
.compile_error => return simpleUnOp(gz, scope, ri, node, .{ .rl = .{ .ty = .slice_const_u8_type } }, params[0], .compile_error),
|
||||
.set_eval_branch_quota => return simpleUnOp(gz, scope, ri, node, .{ .rl = .{ .coerced_ty = .u32_type } }, params[0], .set_eval_branch_quota),
|
||||
.int_from_enum => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, params[0], .int_from_enum),
|
||||
.int_from_bool => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, params[0], .int_from_bool),
|
||||
.embed_file => return simpleUnOp(gz, scope, ri, node, .{ .rl = .{ .ty = .slice_const_u8_type } }, params[0], .embed_file),
|
||||
.error_name => return simpleUnOp(gz, scope, ri, node, .{ .rl = .{ .ty = .anyerror_type } }, params[0], .error_name),
|
||||
.set_runtime_safety => return simpleUnOp(gz, scope, ri, node, bool_ri, params[0], .set_runtime_safety),
|
||||
.sqrt => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, params[0], .sqrt),
|
||||
.sin => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, params[0], .sin),
|
||||
.cos => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, params[0], .cos),
|
||||
.tan => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, params[0], .tan),
|
||||
.exp => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, params[0], .exp),
|
||||
.exp2 => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, params[0], .exp2),
|
||||
.log => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, params[0], .log),
|
||||
.log2 => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, params[0], .log2),
|
||||
.log10 => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, params[0], .log10),
|
||||
.abs => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, params[0], .abs),
|
||||
.floor => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, params[0], .floor),
|
||||
.ceil => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, params[0], .ceil),
|
||||
.trunc => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, params[0], .trunc),
|
||||
.round => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, params[0], .round),
|
||||
.tag_name => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, params[0], .tag_name),
|
||||
.type_name => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, params[0], .type_name),
|
||||
.Frame => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, params[0], .frame_type),
|
||||
.frame_size => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, params[0], .frame_size),
|
||||
.int_from_ptr => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, params[0], .int_from_ptr),
|
||||
.compile_error => return simpleUnOp(gz, scope, ri, node, .{ .rl = .{ .coerced_ty = .slice_const_u8_type } }, params[0], .compile_error),
|
||||
.set_eval_branch_quota => return simpleUnOp(gz, scope, ri, node, .{ .rl = .{ .coerced_ty = .u32_type } }, params[0], .set_eval_branch_quota),
|
||||
.int_from_enum => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, params[0], .int_from_enum),
|
||||
.int_from_bool => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, params[0], .int_from_bool),
|
||||
.embed_file => return simpleUnOp(gz, scope, ri, node, .{ .rl = .{ .coerced_ty = .slice_const_u8_type } }, params[0], .embed_file),
|
||||
.error_name => return simpleUnOp(gz, scope, ri, node, .{ .rl = .{ .coerced_ty = .anyerror_type } }, params[0], .error_name),
|
||||
.set_runtime_safety => return simpleUnOp(gz, scope, ri, node, coerced_bool_ri, params[0], .set_runtime_safety),
|
||||
.sqrt => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, params[0], .sqrt),
|
||||
.sin => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, params[0], .sin),
|
||||
.cos => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, params[0], .cos),
|
||||
.tan => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, params[0], .tan),
|
||||
.exp => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, params[0], .exp),
|
||||
.exp2 => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, params[0], .exp2),
|
||||
.log => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, params[0], .log),
|
||||
.log2 => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, params[0], .log2),
|
||||
.log10 => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, params[0], .log10),
|
||||
.abs => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, params[0], .abs),
|
||||
.floor => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, params[0], .floor),
|
||||
.ceil => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, params[0], .ceil),
|
||||
.trunc => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, params[0], .trunc),
|
||||
.round => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, params[0], .round),
|
||||
.tag_name => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, params[0], .tag_name),
|
||||
.type_name => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, params[0], .type_name),
|
||||
.Frame => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, params[0], .frame_type),
|
||||
.frame_size => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, params[0], .frame_size),
|
||||
|
||||
.int_from_float => return typeCast(gz, scope, ri, node, params[0], .int_from_float, builtin_name),
|
||||
.float_from_int => return typeCast(gz, scope, ri, node, params[0], .float_from_int, builtin_name),
|
||||
@ -9238,7 +9233,7 @@ fn builtinCall(
|
||||
},
|
||||
.panic => {
|
||||
try emitDbgNode(gz, node);
|
||||
return simpleUnOp(gz, scope, ri, node, .{ .rl = .{ .ty = .slice_const_u8_type } }, params[0], .panic);
|
||||
return simpleUnOp(gz, scope, ri, node, .{ .rl = .{ .coerced_ty = .slice_const_u8_type } }, params[0], .panic);
|
||||
},
|
||||
.trap => {
|
||||
try emitDbgNode(gz, node);
|
||||
@ -9327,7 +9322,7 @@ fn builtinCall(
|
||||
},
|
||||
.c_define => {
|
||||
if (!gz.c_import) return gz.astgen.failNode(node, "C define valid only inside C import block", .{});
|
||||
const name = try comptimeExpr(gz, scope, .{ .rl = .{ .ty = .slice_const_u8_type } }, params[0]);
|
||||
const name = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = .slice_const_u8_type } }, params[0]);
|
||||
const value = try comptimeExpr(gz, scope, .{ .rl = .none }, params[1]);
|
||||
const result = try gz.addExtendedPayload(.c_define, Zir.Inst.BinNode{
|
||||
.node = gz.nodeIndexToRelative(node),
|
||||
@ -9348,7 +9343,7 @@ fn builtinCall(
|
||||
return rvalue(gz, ri, result, node);
|
||||
},
|
||||
.reduce => {
|
||||
const op = try expr(gz, scope, .{ .rl = .{ .ty = .reduce_op_type } }, params[0]);
|
||||
const op = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .reduce_op_type } }, params[0]);
|
||||
const scalar = try expr(gz, scope, .{ .rl = .none }, params[1]);
|
||||
const result = try gz.addPlNode(.reduce, node, Zir.Inst.Bin{
|
||||
.lhs = op,
|
||||
@ -9424,7 +9419,7 @@ fn builtinCall(
|
||||
},
|
||||
.field_parent_ptr => {
|
||||
const parent_type = try typeExpr(gz, scope, params[0]);
|
||||
const field_name = try comptimeExpr(gz, scope, .{ .rl = .{ .ty = .slice_const_u8_type } }, params[1]);
|
||||
const field_name = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = .slice_const_u8_type } }, params[1]);
|
||||
const result = try gz.addPlNode(.field_parent_ptr, node, Zir.Inst.FieldParentPtr{
|
||||
.parent_type = parent_type,
|
||||
.field_name = field_name,
|
||||
@ -9561,7 +9556,7 @@ fn hasDeclOrField(
|
||||
tag: Zir.Inst.Tag,
|
||||
) InnerError!Zir.Inst.Ref {
|
||||
const container_type = try typeExpr(gz, scope, lhs_node);
|
||||
const name = try comptimeExpr(gz, scope, .{ .rl = .{ .ty = .slice_const_u8_type } }, rhs_node);
|
||||
const name = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = .slice_const_u8_type } }, rhs_node);
|
||||
const result = try gz.addPlNode(tag, node, Zir.Inst.Bin{
|
||||
.lhs = container_type,
|
||||
.rhs = name,
|
||||
@ -9711,7 +9706,7 @@ fn simpleCBuiltin(
|
||||
) InnerError!Zir.Inst.Ref {
|
||||
const name: []const u8 = if (tag == .c_undef) "C undef" else "C include";
|
||||
if (!gz.c_import) return gz.astgen.failNode(node, "{s} valid only inside C import block", .{name});
|
||||
const operand = try comptimeExpr(gz, scope, .{ .rl = .{ .ty = .slice_const_u8_type } }, operand_node);
|
||||
const operand = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = .slice_const_u8_type } }, operand_node);
|
||||
_ = try gz.addExtendedPayload(tag, Zir.Inst.UnNode{
|
||||
.node = gz.nodeIndexToRelative(node),
|
||||
.operand = operand,
|
||||
@ -9729,7 +9724,7 @@ fn offsetOf(
|
||||
tag: Zir.Inst.Tag,
|
||||
) InnerError!Zir.Inst.Ref {
|
||||
const type_inst = try typeExpr(gz, scope, lhs_node);
|
||||
const field_name = try comptimeExpr(gz, scope, .{ .rl = .{ .ty = .slice_const_u8_type } }, rhs_node);
|
||||
const field_name = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = .slice_const_u8_type } }, rhs_node);
|
||||
const result = try gz.addPlNode(tag, node, Zir.Inst.Bin{
|
||||
.lhs = type_inst,
|
||||
.rhs = field_name,
|
||||
@ -13148,7 +13143,7 @@ const GenZir = struct {
|
||||
fn addRet(gz: *GenZir, ri: ResultInfo, operand: Zir.Inst.Ref, node: Ast.Node.Index) !void {
|
||||
switch (ri.rl) {
|
||||
.ptr => |ptr_res| _ = try gz.addUnNode(.ret_load, ptr_res.inst, node),
|
||||
.ty => _ = try gz.addUnNode(.ret_node, operand, node),
|
||||
.coerced_ty => _ = try gz.addUnNode(.ret_node, operand, node),
|
||||
else => unreachable,
|
||||
}
|
||||
}
|
||||
|
||||
96
src/Sema.zig
96
src/Sema.zig
@ -10487,7 +10487,8 @@ fn zirElemValNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
|
||||
const elem_index_src: LazySrcLoc = .{ .node_offset_array_access_index = inst_data.src_node };
|
||||
const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
|
||||
const array = try sema.resolveInst(extra.lhs);
|
||||
const elem_index = try sema.resolveInst(extra.rhs);
|
||||
const uncoerced_elem_index = try sema.resolveInst(extra.rhs);
|
||||
const elem_index = try sema.coerce(block, Type.usize, uncoerced_elem_index, elem_index_src);
|
||||
return sema.elemVal(block, src, array, elem_index, elem_index_src, true);
|
||||
}
|
||||
|
||||
@ -10539,7 +10540,8 @@ fn zirElemPtrNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
|
||||
const elem_index_src: LazySrcLoc = .{ .node_offset_array_access_index = inst_data.src_node };
|
||||
const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
|
||||
const array_ptr = try sema.resolveInst(extra.lhs);
|
||||
const elem_index = try sema.resolveInst(extra.rhs);
|
||||
const uncoerced_elem_index = try sema.resolveInst(extra.rhs);
|
||||
const elem_index = try sema.coerce(block, Type.usize, uncoerced_elem_index, elem_index_src);
|
||||
return sema.elemPtr(block, src, array_ptr, elem_index, elem_index_src, false, true);
|
||||
}
|
||||
|
||||
@ -18722,11 +18724,13 @@ fn zirBoolBr(
|
||||
const inst_data = datas[@intFromEnum(inst)].pl_node;
|
||||
const extra = sema.code.extraData(Zir.Inst.BoolBr, inst_data.payload_index);
|
||||
|
||||
const lhs = try sema.resolveInst(extra.data.lhs);
|
||||
const uncoerced_lhs = try sema.resolveInst(extra.data.lhs);
|
||||
const body = sema.code.bodySlice(extra.end, extra.data.body_len);
|
||||
const lhs_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node };
|
||||
const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node };
|
||||
|
||||
const lhs = try sema.coerce(parent_block, Type.bool, uncoerced_lhs, lhs_src);
|
||||
|
||||
if (try sema.resolveDefinedValue(parent_block, lhs_src, lhs)) |lhs_val| {
|
||||
if (is_bool_or and lhs_val.toBool()) {
|
||||
return .bool_true;
|
||||
@ -18736,7 +18740,11 @@ fn zirBoolBr(
|
||||
// comptime-known left-hand side. No need for a block here; the result
|
||||
// is simply the rhs expression. Here we rely on there only being 1
|
||||
// break instruction (`break_inline`).
|
||||
return sema.resolveBody(parent_block, body, inst);
|
||||
const rhs_result = try sema.resolveBody(parent_block, body, inst);
|
||||
if (sema.typeOf(rhs_result).isNoReturn(mod)) {
|
||||
return rhs_result;
|
||||
}
|
||||
return sema.coerce(parent_block, Type.bool, rhs_result, rhs_src);
|
||||
}
|
||||
|
||||
const block_inst: Air.Inst.Index = @enumFromInt(sema.air_instructions.len);
|
||||
@ -18767,13 +18775,16 @@ fn zirBoolBr(
|
||||
_ = try lhs_block.addBr(block_inst, lhs_result);
|
||||
|
||||
const rhs_result = try sema.resolveBody(rhs_block, body, inst);
|
||||
if (!sema.typeOf(rhs_result).isNoReturn(mod)) {
|
||||
_ = try rhs_block.addBr(block_inst, rhs_result);
|
||||
}
|
||||
const rhs_noret = sema.typeOf(rhs_result).isNoReturn(mod);
|
||||
const coerced_rhs_result = if (!rhs_noret) rhs: {
|
||||
const coerced_result = try sema.coerce(rhs_block, Type.bool, rhs_result, rhs_src);
|
||||
_ = try rhs_block.addBr(block_inst, coerced_result);
|
||||
break :rhs coerced_result;
|
||||
} else rhs_result;
|
||||
|
||||
const result = sema.finishCondBr(parent_block, &child_block, &then_block, &else_block, lhs, block_inst);
|
||||
if (!sema.typeOf(rhs_result).isNoReturn(mod)) {
|
||||
if (try sema.resolveDefinedValue(rhs_block, rhs_src, rhs_result)) |rhs_val| {
|
||||
if (!rhs_noret) {
|
||||
if (try sema.resolveDefinedValue(rhs_block, rhs_src, coerced_rhs_result)) |rhs_val| {
|
||||
if (is_bool_or and rhs_val.toBool()) {
|
||||
return .bool_true;
|
||||
} else if (!is_bool_or and !rhs_val.toBool()) {
|
||||
@ -20750,8 +20761,9 @@ fn zirIntFromBool(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
|
||||
|
||||
fn zirErrorName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
|
||||
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
|
||||
const operand = try sema.resolveInst(inst_data.operand);
|
||||
const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
|
||||
const uncoerced_operand = try sema.resolveInst(inst_data.operand);
|
||||
const operand = try sema.coerce(block, Type.anyerror, uncoerced_operand, operand_src);
|
||||
|
||||
if (try sema.resolveDefinedValue(block, operand_src, operand)) |val| {
|
||||
const err_name = sema.mod.intern_pool.indexToKey(val.toIntern()).err.name;
|
||||
@ -25375,15 +25387,21 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
|
||||
} else if (extra.data.bits.has_align_ref) blk: {
|
||||
const align_ref: Zir.Inst.Ref = @enumFromInt(sema.code.extra[extra_index]);
|
||||
extra_index += 1;
|
||||
const align_tv = sema.resolveInstConst(block, align_src, align_ref, .{
|
||||
.needed_comptime_reason = "alignment must be comptime-known",
|
||||
}) catch |err| switch (err) {
|
||||
error.GenericPoison => {
|
||||
break :blk null;
|
||||
},
|
||||
const uncoerced_align = sema.resolveInst(align_ref) catch |err| switch (err) {
|
||||
error.GenericPoison => break :blk null,
|
||||
else => |e| return e,
|
||||
};
|
||||
const alignment = try sema.validateAlignAllowZero(block, align_src, try align_tv.val.toUnsignedIntAdvanced(sema));
|
||||
const coerced_align = sema.coerce(block, Type.u29, uncoerced_align, align_src) catch |err| switch (err) {
|
||||
error.GenericPoison => break :blk null,
|
||||
else => |e| return e,
|
||||
};
|
||||
const align_val = sema.resolveConstDefinedValue(block, align_src, coerced_align, .{
|
||||
.needed_comptime_reason = "alignment must be comptime-known",
|
||||
}) catch |err| switch (err) {
|
||||
error.GenericPoison => break :blk null,
|
||||
else => |e| return e,
|
||||
};
|
||||
const alignment = try sema.validateAlignAllowZero(block, align_src, try align_val.toUnsignedIntAdvanced(sema));
|
||||
const default = target_util.defaultFunctionAlignment(target);
|
||||
break :blk if (alignment == default) .none else alignment;
|
||||
} else .none;
|
||||
@ -25394,7 +25412,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
|
||||
const body = sema.code.bodySlice(extra_index, body_len);
|
||||
extra_index += body.len;
|
||||
|
||||
const addrspace_ty = try sema.getBuiltinType("AddressSpace");
|
||||
const addrspace_ty = Type.fromInterned(.address_space_type);
|
||||
const val = try sema.resolveGenericBody(block, addrspace_src, body, inst, addrspace_ty, .{
|
||||
.needed_comptime_reason = "addrspace must be comptime-known",
|
||||
});
|
||||
@ -25405,15 +25423,22 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
|
||||
} else if (extra.data.bits.has_addrspace_ref) blk: {
|
||||
const addrspace_ref: Zir.Inst.Ref = @enumFromInt(sema.code.extra[extra_index]);
|
||||
extra_index += 1;
|
||||
const addrspace_tv = sema.resolveInstConst(block, addrspace_src, addrspace_ref, .{
|
||||
.needed_comptime_reason = "addrspace must be comptime-known",
|
||||
}) catch |err| switch (err) {
|
||||
error.GenericPoison => {
|
||||
break :blk null;
|
||||
},
|
||||
const addrspace_ty = Type.fromInterned(.address_space_type);
|
||||
const uncoerced_addrspace = sema.resolveInst(addrspace_ref) catch |err| switch (err) {
|
||||
error.GenericPoison => break :blk null,
|
||||
else => |e| return e,
|
||||
};
|
||||
break :blk mod.toEnum(std.builtin.AddressSpace, addrspace_tv.val);
|
||||
const coerced_addrspace = sema.coerce(block, addrspace_ty, uncoerced_addrspace, addrspace_src) catch |err| switch (err) {
|
||||
error.GenericPoison => break :blk null,
|
||||
else => |e| return e,
|
||||
};
|
||||
const addrspace_val = sema.resolveConstDefinedValue(block, addrspace_src, coerced_addrspace, .{
|
||||
.needed_comptime_reason = "addrspace must be comptime-known",
|
||||
}) catch |err| switch (err) {
|
||||
error.GenericPoison => break :blk null,
|
||||
else => |e| return e,
|
||||
};
|
||||
break :blk mod.toEnum(std.builtin.AddressSpace, addrspace_val);
|
||||
} else target_util.defaultAddressSpace(target, .function);
|
||||
|
||||
const section: Section = if (extra.data.bits.has_section_body) blk: {
|
||||
@ -25461,15 +25486,22 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
|
||||
} else if (extra.data.bits.has_cc_ref) blk: {
|
||||
const cc_ref: Zir.Inst.Ref = @enumFromInt(sema.code.extra[extra_index]);
|
||||
extra_index += 1;
|
||||
const cc_tv = sema.resolveInstConst(block, cc_src, cc_ref, .{
|
||||
.needed_comptime_reason = "calling convention must be comptime-known",
|
||||
}) catch |err| switch (err) {
|
||||
error.GenericPoison => {
|
||||
break :blk null;
|
||||
},
|
||||
const cc_ty = Type.fromInterned(.calling_convention_type);
|
||||
const uncoerced_cc = sema.resolveInst(cc_ref) catch |err| switch (err) {
|
||||
error.GenericPoison => break :blk null,
|
||||
else => |e| return e,
|
||||
};
|
||||
break :blk mod.toEnum(std.builtin.CallingConvention, cc_tv.val);
|
||||
const coerced_cc = sema.coerce(block, cc_ty, uncoerced_cc, cc_src) catch |err| switch (err) {
|
||||
error.GenericPoison => break :blk null,
|
||||
else => |e| return e,
|
||||
};
|
||||
const cc_val = sema.resolveConstDefinedValue(block, cc_src, coerced_cc, .{
|
||||
.needed_comptime_reason = "calling convention must be comptime-known",
|
||||
}) catch |err| switch (err) {
|
||||
error.GenericPoison => break :blk null,
|
||||
else => |e| return e,
|
||||
};
|
||||
break :blk mod.toEnum(std.builtin.CallingConvention, cc_val);
|
||||
} else if (sema.owner_decl.is_exported and has_body)
|
||||
.C
|
||||
else
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user