lowerNullCoalesce fed resolveOptionalInner's .unresolved (returned for a non-optional lhs) into the merge-block params / optionalUnwrap / RHS target type, reaching codegen and panicking 'unresolved type reached LLVM emission'. Guard: when inferExprType(nc.lhs) is a resolved non-optional type, emit a located diagnostic and bail; an .unresolved lhs (prior error) is excluded to avoid double-report. ?? is optional-only per specs.md (error unions use or/catch), so rejecting a failable lhs is correct; comptime panic closed too. Regression: examples/diagnostics/1200-diagnostics-null-coalesce-non-optional.sx. Verified by 3 adversarial reviews, suite 790/0. Filed adjacent bug 0180 (?? lowering defects for generic/alias/tuple optional lhs).
18 lines
924 B
Plaintext
18 lines
924 B
Plaintext
// `??` (null-coalesce) requires an optional left operand. A resolved
|
|
// non-optional lhs is malformed user input and must be a clean, located type
|
|
// error — not a compiler crash. Regression (issue 0172): `lowerNullCoalesce`
|
|
// used to feed the `.unresolved` inner type (from `resolveOptionalInner` on a
|
|
// non-optional lhs) straight into the merge-block params / `optionalUnwrap` /
|
|
// the RHS target type, which reached emit_llvm's "unresolved type reached LLVM
|
|
// emission" panic (exit 134) with no diagnostic. A guard now inspects the
|
|
// inferred lhs type: a resolved non-optional emits this error and bails before
|
|
// codegen; an already-`.unresolved` lhs (a prior error, e.g. undefined name)
|
|
// passes through untouched so the original diagnostic isn't double-reported.
|
|
|
|
#import "modules/std.sx";
|
|
|
|
main :: () {
|
|
x := 5 ?? 7; // <- left operand of '??' must be an optional, but has type 'i64'
|
|
print("{}\n", x);
|
|
}
|