@@ -1171,11 +1171,11 @@ fn analyzeBodyInner(
1171
1171
.as_node => try sema.zirAsNode(block, inst),
1172
1172
.as_shift_operand => try sema.zirAsShiftOperand(block, inst),
1173
1173
.bit_and => try sema.zirBitwise(block, inst, .bit_and),
1174
- .bit_not => try sema.zirBitNot(block, inst, false ),
1174
+ .bit_not => try sema.zirBitNot(block, inst),
1175
1175
.bit_or => try sema.zirBitwise(block, inst, .bit_or),
1176
1176
.bitcast => try sema.zirBitcast(block, inst),
1177
1177
.suspend_block => try sema.zirSuspendBlock(block, inst),
1178
- .bool_not => try sema.zirBitNot (block, inst, true ),
1178
+ .bool_not => try sema.zirBoolNot (block, inst),
1179
1179
.bool_br_and => try sema.zirBoolBr(block, inst, false),
1180
1180
.bool_br_or => try sema.zirBoolBr(block, inst, true),
1181
1181
.c_import => try sema.zirCImport(block, inst),
@@ -14464,57 +14464,55 @@ fn zirBitwise(
14464
14464
return block.addBinOp(air_tag, casted_lhs, casted_rhs);
14465
14465
}
14466
14466
14467
- fn zirBitNot(
14468
- sema: *Sema,
14469
- block: *Block,
14470
- inst: Zir.Inst.Index,
14471
- is_bool_not: bool,
14472
- ) CompileError!Air.Inst.Ref {
14473
- const tracy = trace(@src());
14474
- defer tracy.end();
14475
-
14467
+ fn zirBitNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
14476
14468
const pt = sema.pt;
14477
14469
const zcu = pt.zcu;
14478
14470
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
14479
- const src = block.nodeOffset(inst_data.src_node);
14480
14471
const operand_src = block.src(.{ .node_offset_un_op = inst_data.src_node });
14481
-
14472
+ const src = block.nodeOffset(inst_data.src_node);
14482
14473
const operand = try sema.resolveInst(inst_data.operand);
14483
- const operand_type = sema.typeOf(operand);
14484
- const scalar_type = operand_type .scalarType(zcu);
14485
- const scalar_tag = scalar_type .zigTypeTag(zcu);
14474
+ const operand_ty = sema.typeOf(operand);
14475
+ const scalar_ty = operand_ty .scalarType(zcu);
14476
+ const scalar_tag = scalar_ty .zigTypeTag(zcu);
14486
14477
14487
- const is_finite_int_or_bool = scalar_tag == .int or scalar_tag == .bool;
14488
- const is_allowed_type = if (is_bool_not) scalar_tag == .bool else is_finite_int_or_bool ;
14478
+ if ( scalar_tag != .int and scalar_tag != .bool)
14479
+ return sema.fail(block, operand_src, "bitwise not operation on type '{}'", .{operand_ty.fmt(pt)}) ;
14489
14480
14490
- if (!is_allowed_type) {
14491
- return sema.fail(block, src, "unable to perform {s} not operation on type '{}'", .{
14492
- if (is_bool_not) "boolean" else "binary", operand_type.fmt(pt),
14493
- });
14494
- }
14481
+ return analyzeBitNot(sema, block, operand, src);
14482
+ }
14495
14483
14484
+ fn analyzeBitNot(
14485
+ sema: *Sema,
14486
+ block: *Block,
14487
+ operand: Air.Inst.Ref,
14488
+ src: LazySrcLoc,
14489
+ ) CompileError!Air.Inst.Ref {
14490
+ const pt = sema.pt;
14491
+ const zcu = pt.zcu;
14492
+ const operand_ty = sema.typeOf(operand);
14493
+ const scalar_ty = operand_ty.scalarType(zcu);
14496
14494
if (try sema.resolveValue(operand)) |val| {
14497
14495
if (val.isUndef(zcu)) {
14498
- return pt.undefRef(operand_type );
14499
- } else if (operand_type .zigTypeTag(zcu) == .vector) {
14500
- const vec_len = try sema.usizeCast(block, operand_src, operand_type .vectorLen(zcu));
14496
+ return pt.undefRef(operand_ty );
14497
+ } else if (operand_ty .zigTypeTag(zcu) == .vector) {
14498
+ const vec_len = try sema.usizeCast(block, src, operand_ty .vectorLen(zcu));
14501
14499
const elems = try sema.arena.alloc(InternPool.Index, vec_len);
14502
14500
for (elems, 0..) |*elem, i| {
14503
14501
const elem_val = try val.elemValue(pt, i);
14504
- elem.* = (try elem_val.bitwiseNot(scalar_type , sema.arena, pt)).toIntern();
14502
+ elem.* = (try elem_val.bitwiseNot(scalar_ty , sema.arena, pt)).toIntern();
14505
14503
}
14506
14504
return Air.internedToRef((try pt.intern(.{ .aggregate = .{
14507
- .ty = operand_type .toIntern(),
14505
+ .ty = operand_ty .toIntern(),
14508
14506
.storage = .{ .elems = elems },
14509
14507
} })));
14510
14508
} else {
14511
- const result_val = try val.bitwiseNot(operand_type , sema.arena, pt);
14509
+ const result_val = try val.bitwiseNot(operand_ty , sema.arena, pt);
14512
14510
return Air.internedToRef(result_val.toIntern());
14513
14511
}
14514
14512
}
14515
14513
14516
14514
try sema.requireRuntimeBlock(block, src, null);
14517
- return block.addTyOp(.not, operand_type , operand);
14515
+ return block.addTyOp(.not, operand_ty , operand);
14518
14516
}
14519
14517
14520
14518
fn analyzeTupleCat(
@@ -18367,6 +18365,30 @@ fn zirTypeofPeer(
18367
18365
return Air.internedToRef(result_type.toIntern());
18368
18366
}
18369
18367
18368
+ fn zirBoolNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
18369
+ const pt = sema.pt;
18370
+ const zcu = pt.zcu;
18371
+ const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
18372
+ const src = block.nodeOffset(inst_data.src_node);
18373
+ const operand_src = block.src(.{ .node_offset_un_op = inst_data.src_node });
18374
+ const uncasted_operand = try sema.resolveInst(inst_data.operand);
18375
+ const uncasted_ty = sema.typeOf(uncasted_operand);
18376
+ if (uncasted_ty.isVector(zcu)) {
18377
+ if (uncasted_ty.scalarType(zcu).zigTypeTag(zcu) != .bool) {
18378
+ return sema.fail(block, operand_src, "boolean not operation on type '{}'", .{
18379
+ uncasted_ty.fmt(pt),
18380
+ });
18381
+ }
18382
+ return analyzeBitNot(sema, block, uncasted_operand, src);
18383
+ }
18384
+ const operand = try sema.coerce(block, .bool, uncasted_operand, operand_src);
18385
+ if (try sema.resolveValue(operand)) |val| {
18386
+ return if (val.isUndef(zcu)) .undef_bool else if (val.toBool()) .bool_false else .bool_true;
18387
+ }
18388
+ try sema.requireRuntimeBlock(block, src, null);
18389
+ return block.addTyOp(.not, .bool, operand);
18390
+ }
18391
+
18370
18392
fn zirBoolBr(
18371
18393
sema: *Sema,
18372
18394
parent_block: *Block,
0 commit comments