authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-02-01 13:38:56-05:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2022-02-01 13:38:56-05:00
log217025e9f0a3c3ce3c0d761352d0fa8b41aa5d3b
treec4b3d86e2dfed1a9cbf4af1f9c9c3a06b42fe4c3
parent3e99495ed8d2a384501338edb4885e709d51bf74
parent4188d541303c9375a7ce9533a8cfe72f69466b4c
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #10751 from mitchellh/stage2/cmp-eq-undefined

stage2: cmp between untyped undefines values results in undef bool

2 files changed, 21 insertions(+), 24 deletions(-)

src/Sema.zig+21-22
...@@ -1163,7 +1163,7 @@ fn resolveConstBool(...@@ -1163,7 +1163,7 @@ fn resolveConstBool(
1163 zir_ref: Zir.Inst.Ref,1163 zir_ref: Zir.Inst.Ref,
1164) !bool {1164) !bool {
1165 const air_inst = sema.resolveInst(zir_ref);1165 const air_inst = sema.resolveInst(zir_ref);
1166 const wanted_type = Type.initTag(.bool);1166 const wanted_type = Type.bool;
1167 const coerced_inst = try sema.coerce(block, wanted_type, air_inst, src);1167 const coerced_inst = try sema.coerce(block, wanted_type, air_inst, src);
1168 const val = try sema.resolveConstValue(block, src, coerced_inst);1168 const val = try sema.resolveConstValue(block, src, coerced_inst);
1169 return val.toBool();1169 return val.toBool();
...@@ -8058,7 +8058,7 @@ fn zirOverflowArithmetic(...@@ -8058,7 +8058,7 @@ fn zirOverflowArithmetic(
8058 return switch (result.overflowed) {8058 return switch (result.overflowed) {
8059 .yes => Air.Inst.Ref.bool_true,8059 .yes => Air.Inst.Ref.bool_true,
8060 .no => Air.Inst.Ref.bool_false,8060 .no => Air.Inst.Ref.bool_false,
8061 .undef => try sema.addConstUndef(Type.initTag(.bool)),8061 .undef => try sema.addConstUndef(Type.bool),
8062 };8062 };
8063}8063}
80648064
...@@ -9125,7 +9125,7 @@ fn zirCmpEq(...@@ -9125,7 +9125,7 @@ fn zirCmpEq(
9125 if (try sema.resolveMaybeUndefVal(block, lhs_src, lhs)) |lval| {9125 if (try sema.resolveMaybeUndefVal(block, lhs_src, lhs)) |lval| {
9126 if (try sema.resolveMaybeUndefVal(block, rhs_src, rhs)) |rval| {9126 if (try sema.resolveMaybeUndefVal(block, rhs_src, rhs)) |rval| {
9127 if (lval.isUndef() or rval.isUndef()) {9127 if (lval.isUndef() or rval.isUndef()) {
9128 return sema.addConstUndef(Type.initTag(.bool));9128 return sema.addConstUndef(Type.bool);
9129 }9129 }
9130 // TODO optimisation opportunity: evaluate if mem.eql is faster with the names,9130 // TODO optimisation opportunity: evaluate if mem.eql is faster with the names,
9131 // or calling to Module.getErrorValue to get the values and then compare them is9131 // or calling to Module.getErrorValue to get the values and then compare them is
...@@ -9244,9 +9244,9 @@ fn cmpSelf(...@@ -9244,9 +9244,9 @@ fn cmpSelf(
9244 const resolved_type = sema.typeOf(casted_lhs);9244 const resolved_type = sema.typeOf(casted_lhs);
9245 const runtime_src: LazySrcLoc = src: {9245 const runtime_src: LazySrcLoc = src: {
9246 if (try sema.resolveMaybeUndefVal(block, lhs_src, casted_lhs)) |lhs_val| {9246 if (try sema.resolveMaybeUndefVal(block, lhs_src, casted_lhs)) |lhs_val| {
9247 if (lhs_val.isUndef()) return sema.addConstUndef(resolved_type);9247 if (lhs_val.isUndef()) return sema.addConstUndef(Type.bool);
9248 if (try sema.resolveMaybeUndefVal(block, rhs_src, casted_rhs)) |rhs_val| {9248 if (try sema.resolveMaybeUndefVal(block, rhs_src, casted_rhs)) |rhs_val| {
9249 if (rhs_val.isUndef()) return sema.addConstUndef(resolved_type);9249 if (rhs_val.isUndef()) return sema.addConstUndef(Type.bool);
92509250
9251 if (lhs_val.compare(op, rhs_val, resolved_type)) {9251 if (lhs_val.compare(op, rhs_val, resolved_type)) {
9252 return Air.Inst.Ref.bool_true;9252 return Air.Inst.Ref.bool_true;
...@@ -9265,7 +9265,7 @@ fn cmpSelf(...@@ -9265,7 +9265,7 @@ fn cmpSelf(
9265 // bool eq/neq more efficiently.9265 // bool eq/neq more efficiently.
9266 if (resolved_type.zigTypeTag() == .Bool) {9266 if (resolved_type.zigTypeTag() == .Bool) {
9267 if (try sema.resolveMaybeUndefVal(block, rhs_src, casted_rhs)) |rhs_val| {9267 if (try sema.resolveMaybeUndefVal(block, rhs_src, casted_rhs)) |rhs_val| {
9268 if (rhs_val.isUndef()) return sema.addConstUndef(resolved_type);9268 if (rhs_val.isUndef()) return sema.addConstUndef(Type.bool);
9269 return sema.runtimeBoolCmp(block, op, casted_lhs, rhs_val.toBool(), lhs_src);9269 return sema.runtimeBoolCmp(block, op, casted_lhs, rhs_val.toBool(), lhs_src);
9270 }9270 }
9271 }9271 }
...@@ -9300,7 +9300,7 @@ fn runtimeBoolCmp(...@@ -9300,7 +9300,7 @@ fn runtimeBoolCmp(
9300) CompileError!Air.Inst.Ref {9300) CompileError!Air.Inst.Ref {
9301 if ((op == .neq) == rhs) {9301 if ((op == .neq) == rhs) {
9302 try sema.requireRuntimeBlock(block, runtime_src);9302 try sema.requireRuntimeBlock(block, runtime_src);
9303 return block.addTyOp(.not, Type.initTag(.bool), lhs);9303 return block.addTyOp(.not, Type.bool, lhs);
9304 } else {9304 } else {
9305 return lhs;9305 return lhs;
9306 }9306 }
...@@ -9545,9 +9545,9 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -9545,9 +9545,9 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
9545 // alignment: comptime_int,9545 // alignment: comptime_int,
9546 field_values[1] = try Value.Tag.int_u64.create(sema.arena, ty.abiAlignment(target));9546 field_values[1] = try Value.Tag.int_u64.create(sema.arena, ty.abiAlignment(target));
9547 // is_generic: bool,9547 // is_generic: bool,
9548 field_values[2] = if (info.is_generic) Value.initTag(.bool_true) else Value.initTag(.bool_false);9548 field_values[2] = if (info.is_generic) Value.@"true" else Value.@"false";
9549 // is_var_args: bool,9549 // is_var_args: bool,
9550 field_values[3] = if (info.is_var_args) Value.initTag(.bool_true) else Value.initTag(.bool_false);9550 field_values[3] = if (info.is_var_args) Value.@"true" else Value.@"false";
9551 // return_type: ?type,9551 // return_type: ?type,
9552 field_values[4] = try Value.Tag.ty.create(sema.arena, ty.fnReturnType());9552 field_values[4] = try Value.Tag.ty.create(sema.arena, ty.fnReturnType());
9553 // args: []const FnArg,9553 // args: []const FnArg,
...@@ -9599,9 +9599,9 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -9599,9 +9599,9 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
9599 // size: Size,9599 // size: Size,
9600 field_values[0] = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(info.size));9600 field_values[0] = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(info.size));
9601 // is_const: bool,9601 // is_const: bool,
9602 field_values[1] = if (!info.mutable) Value.initTag(.bool_true) else Value.initTag(.bool_false);9602 field_values[1] = if (!info.mutable) Value.@"true" else Value.@"false";
9603 // is_volatile: bool,9603 // is_volatile: bool,
9604 field_values[2] = if (info.@"volatile") Value.initTag(.bool_true) else Value.initTag(.bool_false);9604 field_values[2] = if (info.@"volatile") Value.@"true" else Value.@"false";
9605 // alignment: comptime_int,9605 // alignment: comptime_int,
9606 field_values[3] = try Value.Tag.int_u64.create(sema.arena, info.@"align");9606 field_values[3] = try Value.Tag.int_u64.create(sema.arena, info.@"align");
9607 // address_space: AddressSpace9607 // address_space: AddressSpace
...@@ -9609,7 +9609,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -9609,7 +9609,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
9609 // child: type,9609 // child: type,
9610 field_values[5] = try Value.Tag.ty.create(sema.arena, info.pointee_type);9610 field_values[5] = try Value.Tag.ty.create(sema.arena, info.pointee_type);
9611 // is_allowzero: bool,9611 // is_allowzero: bool,
9612 field_values[6] = if (info.@"allowzero") Value.initTag(.bool_true) else Value.initTag(.bool_false);9612 field_values[6] = if (info.@"allowzero") Value.@"true" else Value.@"false";
9613 // sentinel: anytype,9613 // sentinel: anytype,
9614 field_values[7] = if (info.sentinel) |some| try Value.Tag.opt_payload.create(sema.arena, some) else Value.@"null";9614 field_values[7] = if (info.sentinel) |some| try Value.Tag.opt_payload.create(sema.arena, some) else Value.@"null";
96159615
...@@ -10060,18 +10060,17 @@ fn zirBoolNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -10060,18 +10060,17 @@ fn zirBoolNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
10060 const operand_src = src; // TODO put this on the operand, not the `!`10060 const operand_src = src; // TODO put this on the operand, not the `!`
10061 const uncasted_operand = sema.resolveInst(inst_data.operand);10061 const uncasted_operand = sema.resolveInst(inst_data.operand);
1006210062
10063 const bool_type = Type.initTag(.bool);10063 const operand = try sema.coerce(block, Type.bool, uncasted_operand, operand_src);
10064 const operand = try sema.coerce(block, bool_type, uncasted_operand, operand_src);
10065 if (try sema.resolveMaybeUndefVal(block, operand_src, operand)) |val| {10064 if (try sema.resolveMaybeUndefVal(block, operand_src, operand)) |val| {
10066 return if (val.isUndef())10065 return if (val.isUndef())
10067 sema.addConstUndef(bool_type)10066 sema.addConstUndef(Type.bool)
10068 else if (val.toBool())10067 else if (val.toBool())
10069 Air.Inst.Ref.bool_false10068 Air.Inst.Ref.bool_false
10070 else10069 else
10071 Air.Inst.Ref.bool_true;10070 Air.Inst.Ref.bool_true;
10072 }10071 }
10073 try sema.requireRuntimeBlock(block, src);10072 try sema.requireRuntimeBlock(block, src);
10074 return block.addTyOp(.not, bool_type, operand);10073 return block.addTyOp(.not, Type.bool, operand);
10075}10074}
1007610075
10077fn zirBoolBr(10076fn zirBoolBr(
...@@ -10229,7 +10228,7 @@ fn zirCondbr(...@@ -10229,7 +10228,7 @@ fn zirCondbr(
10229 const else_body = sema.code.extra[extra.end + then_body.len ..][0..extra.data.else_body_len];10228 const else_body = sema.code.extra[extra.end + then_body.len ..][0..extra.data.else_body_len];
1023010229
10231 const uncasted_cond = sema.resolveInst(extra.data.condition);10230 const uncasted_cond = sema.resolveInst(extra.data.condition);
10232 const cond = try sema.coerce(parent_block, Type.initTag(.bool), uncasted_cond, cond_src);10231 const cond = try sema.coerce(parent_block, Type.bool, uncasted_cond, cond_src);
1023310232
10234 if (try sema.resolveDefinedValue(parent_block, src, cond)) |cond_val| {10233 if (try sema.resolveDefinedValue(parent_block, src, cond)) |cond_val| {
10235 const body = if (cond_val.toBool()) then_body else else_body;10234 const body = if (cond_val.toBool()) then_body else else_body;
...@@ -15537,7 +15536,7 @@ fn analyzeIsNull(...@@ -15537,7 +15536,7 @@ fn analyzeIsNull(
15537 operand: Air.Inst.Ref,15536 operand: Air.Inst.Ref,
15538 invert_logic: bool,15537 invert_logic: bool,
15539) CompileError!Air.Inst.Ref {15538) CompileError!Air.Inst.Ref {
15540 const result_ty = Type.initTag(.bool);15539 const result_ty = Type.bool;
15541 if (try sema.resolveMaybeUndefVal(block, src, operand)) |opt_val| {15540 if (try sema.resolveMaybeUndefVal(block, src, operand)) |opt_val| {
15542 if (opt_val.isUndef()) {15541 if (opt_val.isUndef()) {
15543 return sema.addConstUndef(result_ty);15542 return sema.addConstUndef(result_ty);
...@@ -15566,7 +15565,7 @@ fn analyzeIsNonErr(...@@ -15566,7 +15565,7 @@ fn analyzeIsNonErr(
15566 if (ot != .ErrorSet and ot != .ErrorUnion) return Air.Inst.Ref.bool_true;15565 if (ot != .ErrorSet and ot != .ErrorUnion) return Air.Inst.Ref.bool_true;
15567 if (ot == .ErrorSet) return Air.Inst.Ref.bool_false;15566 if (ot == .ErrorSet) return Air.Inst.Ref.bool_false;
15568 assert(ot == .ErrorUnion);15567 assert(ot == .ErrorUnion);
15569 const result_ty = Type.initTag(.bool);15568 const result_ty = Type.bool;
15570 if (try sema.resolveMaybeUndefVal(block, src, operand)) |err_union| {15569 if (try sema.resolveMaybeUndefVal(block, src, operand)) |err_union| {
15571 if (err_union.isUndef()) {15570 if (err_union.isUndef()) {
15572 return sema.addConstUndef(result_ty);15571 return sema.addConstUndef(result_ty);
...@@ -15769,7 +15768,7 @@ fn cmpNumeric(...@@ -15769,7 +15768,7 @@ fn cmpNumeric(
15769 if (try sema.resolveMaybeUndefVal(block, lhs_src, lhs)) |lhs_val| {15768 if (try sema.resolveMaybeUndefVal(block, lhs_src, lhs)) |lhs_val| {
15770 if (try sema.resolveMaybeUndefVal(block, rhs_src, rhs)) |rhs_val| {15769 if (try sema.resolveMaybeUndefVal(block, rhs_src, rhs)) |rhs_val| {
15771 if (lhs_val.isUndef() or rhs_val.isUndef()) {15770 if (lhs_val.isUndef() or rhs_val.isUndef()) {
15772 return sema.addConstUndef(Type.initTag(.bool));15771 return sema.addConstUndef(Type.bool);
15773 }15772 }
15774 if (Value.compareHetero(lhs_val, op, rhs_val)) {15773 if (Value.compareHetero(lhs_val, op, rhs_val)) {
15775 return Air.Inst.Ref.bool_true;15774 return Air.Inst.Ref.bool_true;
...@@ -15840,7 +15839,7 @@ fn cmpNumeric(...@@ -15840,7 +15839,7 @@ fn cmpNumeric(
15840 var lhs_bits: usize = undefined;15839 var lhs_bits: usize = undefined;
15841 if (try sema.resolveMaybeUndefVal(block, lhs_src, lhs)) |lhs_val| {15840 if (try sema.resolveMaybeUndefVal(block, lhs_src, lhs)) |lhs_val| {
15842 if (lhs_val.isUndef())15841 if (lhs_val.isUndef())
15843 return sema.addConstUndef(Type.initTag(.bool));15842 return sema.addConstUndef(Type.bool);
15844 const is_unsigned = if (lhs_is_float) x: {15843 const is_unsigned = if (lhs_is_float) x: {
15845 var bigint_space: Value.BigIntSpace = undefined;15844 var bigint_space: Value.BigIntSpace = undefined;
15846 var bigint = try lhs_val.toBigInt(&bigint_space).toManaged(sema.gpa);15845 var bigint = try lhs_val.toBigInt(&bigint_space).toManaged(sema.gpa);
...@@ -15875,7 +15874,7 @@ fn cmpNumeric(...@@ -15875,7 +15874,7 @@ fn cmpNumeric(
15875 var rhs_bits: usize = undefined;15874 var rhs_bits: usize = undefined;
15876 if (try sema.resolveMaybeUndefVal(block, rhs_src, rhs)) |rhs_val| {15875 if (try sema.resolveMaybeUndefVal(block, rhs_src, rhs)) |rhs_val| {
15877 if (rhs_val.isUndef())15876 if (rhs_val.isUndef())
15878 return sema.addConstUndef(Type.initTag(.bool));15877 return sema.addConstUndef(Type.bool);
15879 const is_unsigned = if (rhs_is_float) x: {15878 const is_unsigned = if (rhs_is_float) x: {
15880 var bigint_space: Value.BigIntSpace = undefined;15879 var bigint_space: Value.BigIntSpace = undefined;
15881 var bigint = try rhs_val.toBigInt(&bigint_space).toManaged(sema.gpa);15880 var bigint = try rhs_val.toBigInt(&bigint_space).toManaged(sema.gpa);
test/behavior/math.zig-2
...@@ -1024,8 +1024,6 @@ test "vector comparison" {...@@ -1024,8 +1024,6 @@ test "vector comparison" {
1024}1024}
10251025
1026test "compare undefined literal with comptime_int" {1026test "compare undefined literal with comptime_int" {
1027 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
1028
1029 var x = undefined == 1;1027 var x = undefined == 1;
1030 // x is now undefined with type bool1028 // x is now undefined with type bool
1031 x = true;1029 x = true;