mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 13:54:21 +00:00
sema: strip @splat operand result type before checking it
This commit is contained in:
parent
6e90ce2536
commit
8e02f9f70d
5 changed files with 33 additions and 14 deletions
|
|
@ -2697,7 +2697,7 @@ fn addEnsureResult(gz: *GenZir, maybe_unused_result: Zir.Inst.Ref, statement: As
|
||||||
.array_type_sentinel,
|
.array_type_sentinel,
|
||||||
.elem_type,
|
.elem_type,
|
||||||
.indexable_ptr_elem_type,
|
.indexable_ptr_elem_type,
|
||||||
.vec_arr_elem_type,
|
.splat_op_result_ty,
|
||||||
.vector_type,
|
.vector_type,
|
||||||
.indexable_ptr_len,
|
.indexable_ptr_len,
|
||||||
.anyframe_type,
|
.anyframe_type,
|
||||||
|
|
@ -9526,10 +9526,9 @@ fn builtinCall(
|
||||||
});
|
});
|
||||||
return rvalue(gz, ri, result, node);
|
return rvalue(gz, ri, result, node);
|
||||||
},
|
},
|
||||||
|
|
||||||
.splat => {
|
.splat => {
|
||||||
const result_type = try ri.rl.resultTypeForCast(gz, node, builtin_name);
|
const result_type = try ri.rl.resultTypeForCast(gz, node, builtin_name);
|
||||||
const elem_type = try gz.addUnNode(.vec_arr_elem_type, result_type, node);
|
const elem_type = try gz.addUnNode(.splat_op_result_ty, result_type, node);
|
||||||
const scalar = try expr(gz, scope, .{ .rl = .{ .ty = elem_type } }, params[0]);
|
const scalar = try expr(gz, scope, .{ .rl = .{ .ty = elem_type } }, params[0]);
|
||||||
const result = try gz.addPlNode(.splat, node, Zir.Inst.Bin{
|
const result = try gz.addPlNode(.splat, node, Zir.Inst.Bin{
|
||||||
.lhs = result_type,
|
.lhs = result_type,
|
||||||
|
|
|
||||||
|
|
@ -273,9 +273,13 @@ pub const Inst = struct {
|
||||||
/// element type. Emits a compile error if the type is not an indexable pointer.
|
/// element type. Emits a compile error if the type is not an indexable pointer.
|
||||||
/// Uses the `un_node` field.
|
/// Uses the `un_node` field.
|
||||||
indexable_ptr_elem_type,
|
indexable_ptr_elem_type,
|
||||||
/// Given a vector or array type, returns its element type.
|
/// Given a vector or array type, strips off any error unions or
|
||||||
|
/// optionals layered on top and returns its element type.
|
||||||
|
///
|
||||||
|
/// `!?[N]T` -> `T`
|
||||||
|
///
|
||||||
/// Uses the `un_node` field.
|
/// Uses the `un_node` field.
|
||||||
vec_arr_elem_type,
|
splat_op_result_ty,
|
||||||
/// Given a pointer to an indexable object, returns the len property. This is
|
/// Given a pointer to an indexable object, returns the len property. This is
|
||||||
/// used by for loops. This instruction also emits a for-loop specific compile
|
/// used by for loops. This instruction also emits a for-loop specific compile
|
||||||
/// error if the indexable object is not indexable.
|
/// error if the indexable object is not indexable.
|
||||||
|
|
@ -1098,7 +1102,7 @@ pub const Inst = struct {
|
||||||
.vector_type,
|
.vector_type,
|
||||||
.elem_type,
|
.elem_type,
|
||||||
.indexable_ptr_elem_type,
|
.indexable_ptr_elem_type,
|
||||||
.vec_arr_elem_type,
|
.splat_op_result_ty,
|
||||||
.indexable_ptr_len,
|
.indexable_ptr_len,
|
||||||
.anyframe_type,
|
.anyframe_type,
|
||||||
.as_node,
|
.as_node,
|
||||||
|
|
@ -1395,7 +1399,7 @@ pub const Inst = struct {
|
||||||
.vector_type,
|
.vector_type,
|
||||||
.elem_type,
|
.elem_type,
|
||||||
.indexable_ptr_elem_type,
|
.indexable_ptr_elem_type,
|
||||||
.vec_arr_elem_type,
|
.splat_op_result_ty,
|
||||||
.indexable_ptr_len,
|
.indexable_ptr_len,
|
||||||
.anyframe_type,
|
.anyframe_type,
|
||||||
.as_node,
|
.as_node,
|
||||||
|
|
@ -1630,7 +1634,7 @@ pub const Inst = struct {
|
||||||
.vector_type = .pl_node,
|
.vector_type = .pl_node,
|
||||||
.elem_type = .un_node,
|
.elem_type = .un_node,
|
||||||
.indexable_ptr_elem_type = .un_node,
|
.indexable_ptr_elem_type = .un_node,
|
||||||
.vec_arr_elem_type = .un_node,
|
.splat_op_result_ty = .un_node,
|
||||||
.indexable_ptr_len = .un_node,
|
.indexable_ptr_len = .un_node,
|
||||||
.anyframe_type = .un_node,
|
.anyframe_type = .un_node,
|
||||||
.as_node = .pl_node,
|
.as_node = .pl_node,
|
||||||
|
|
@ -4173,7 +4177,7 @@ fn findTrackableInner(
|
||||||
.vector_type,
|
.vector_type,
|
||||||
.elem_type,
|
.elem_type,
|
||||||
.indexable_ptr_elem_type,
|
.indexable_ptr_elem_type,
|
||||||
.vec_arr_elem_type,
|
.splat_op_result_ty,
|
||||||
.indexable_ptr_len,
|
.indexable_ptr_len,
|
||||||
.anyframe_type,
|
.anyframe_type,
|
||||||
.as_node,
|
.as_node,
|
||||||
|
|
|
||||||
11
src/Sema.zig
11
src/Sema.zig
|
|
@ -1197,7 +1197,7 @@ fn analyzeBodyInner(
|
||||||
.elem_val_imm => try sema.zirElemValImm(block, inst),
|
.elem_val_imm => try sema.zirElemValImm(block, inst),
|
||||||
.elem_type => try sema.zirElemType(block, inst),
|
.elem_type => try sema.zirElemType(block, inst),
|
||||||
.indexable_ptr_elem_type => try sema.zirIndexablePtrElemType(block, inst),
|
.indexable_ptr_elem_type => try sema.zirIndexablePtrElemType(block, inst),
|
||||||
.vec_arr_elem_type => try sema.zirVecArrElemType(block, inst),
|
.splat_op_result_ty => try sema.zirSplatOpResultType(block, inst),
|
||||||
.enum_literal => try sema.zirEnumLiteral(block, inst),
|
.enum_literal => try sema.zirEnumLiteral(block, inst),
|
||||||
.decl_literal => try sema.zirDeclLiteral(block, inst, true),
|
.decl_literal => try sema.zirDeclLiteral(block, inst, true),
|
||||||
.decl_literal_no_coerce => try sema.zirDeclLiteral(block, inst, false),
|
.decl_literal_no_coerce => try sema.zirDeclLiteral(block, inst, false),
|
||||||
|
|
@ -2139,7 +2139,7 @@ fn genericPoisonReason(sema: *Sema, block: *Block, ref: Zir.Inst.Ref) GenericPoi
|
||||||
const bin = sema.code.instructions.items(.data)[@intFromEnum(inst)].bin;
|
const bin = sema.code.instructions.items(.data)[@intFromEnum(inst)].bin;
|
||||||
cur = bin.lhs;
|
cur = bin.lhs;
|
||||||
},
|
},
|
||||||
.indexable_ptr_elem_type, .vec_arr_elem_type => {
|
.indexable_ptr_elem_type, .splat_op_result_ty => {
|
||||||
const un_node = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
|
const un_node = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
|
||||||
cur = un_node.operand;
|
cur = un_node.operand;
|
||||||
},
|
},
|
||||||
|
|
@ -7945,11 +7945,14 @@ fn zirIndexablePtrElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com
|
||||||
return Air.internedToRef(elem_ty.toIntern());
|
return Air.internedToRef(elem_ty.toIntern());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn zirVecArrElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
|
fn zirSplatOpResultType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
|
||||||
const pt = sema.pt;
|
const pt = sema.pt;
|
||||||
const zcu = pt.zcu;
|
const zcu = pt.zcu;
|
||||||
const un_node = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
|
const un_node = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
|
||||||
const vec_ty = try sema.resolveTypeOrPoison(block, LazySrcLoc.unneeded, un_node.operand) orelse return .generic_poison_type;
|
|
||||||
|
const raw_ty = try sema.resolveTypeOrPoison(block, LazySrcLoc.unneeded, un_node.operand) orelse return .generic_poison_type;
|
||||||
|
const vec_ty = raw_ty.optEuBaseType(zcu);
|
||||||
|
|
||||||
switch (vec_ty.zigTypeTag(zcu)) {
|
switch (vec_ty.zigTypeTag(zcu)) {
|
||||||
.array, .vector => {},
|
.array, .vector => {},
|
||||||
else => return sema.fail(block, block.nodeOffset(un_node.src_node), "expected array or vector type, found '{f}'", .{vec_ty.fmt(pt)}),
|
else => return sema.fail(block, block.nodeOffset(un_node.src_node), "expected array or vector type, found '{f}'", .{vec_ty.fmt(pt)}),
|
||||||
|
|
|
||||||
|
|
@ -192,7 +192,7 @@ const Writer = struct {
|
||||||
.alloc_comptime_mut,
|
.alloc_comptime_mut,
|
||||||
.elem_type,
|
.elem_type,
|
||||||
.indexable_ptr_elem_type,
|
.indexable_ptr_elem_type,
|
||||||
.vec_arr_elem_type,
|
.splat_op_result_ty,
|
||||||
.indexable_ptr_len,
|
.indexable_ptr_len,
|
||||||
.anyframe_type,
|
.anyframe_type,
|
||||||
.bit_not,
|
.bit_not,
|
||||||
|
|
|
||||||
|
|
@ -1112,3 +1112,16 @@ test "sentinel of runtime-known array initialization is populated" {
|
||||||
try expect(elems[0] == 42);
|
try expect(elems[0] == 42);
|
||||||
try expect(elems[1] == 123);
|
try expect(elems[1] == 123);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test "splat with an error union or optional result type" {
|
||||||
|
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||||
|
|
||||||
|
const S = struct {
|
||||||
|
fn doTest(T: type) !?T {
|
||||||
|
return @splat(1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
_ = try S.doTest(@Vector(4, u32));
|
||||||
|
_ = try S.doTest([4]u32);
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue