// String `==`/`!=` as an operand of a short-circuit `and`/`or`. // // A string compare lowers to its own multi-block memcmp sub-CFG, so the // operand finishes in a later basic block than the one the short-circuit // started in. The `and`/`or` merge PHI must take that actual block as the // incoming predecessor. // // Regression (issue 0078): combining string equality with `and`/`or` used to // emit invalid LLVM (`PHI node entries do not match predecessors!`). #import "modules/std.sx"; Json :: enum { str: string; int_: s64; null_; } main :: () { a := "k"; b := "v"; // string == on both sides of `and` and_tt := a == "k" and b == "v"; and_tf := a == "k" and b == "x"; and_ft := a == "z" and b == "v"; print("and: {} {} {}\n", and_tt, and_tf, and_ft); // string == on both sides of `or` or_ff := a == "z" or b == "x"; or_tf := a == "k" or b == "x"; or_ft := a == "z" or b == "v"; print("or: {} {} {}\n", or_ff, or_tf, or_ft); // string == feeding both `and` and `or` in one expression mixed := a == "k" and b == "v" or a == "z"; print("mixed: {}\n", mixed); // string `!=` operands too ne := a != "z" and b != "z"; print("ne: {}\n", ne); // the larger shape: a match-expression value plus an enum-payload string // == combined under `and`/`or`. v : Json = .str("v"); kind := if v == { case .str: 1; case .int_: 2; case .null_: 3; } ok := kind == 1 and v.str == "v"; bad := kind == 2 or v.str == "x"; print("payload: {} {}\n", ok, bad); }