aboutsummaryrefslogtreecommitdiff
path: root/src/Sema.zig
diff options
context:
space:
mode:
authorVeikka Tuominen <git@vexu.eu>2022-08-17 13:10:58 +0300
committerVeikka Tuominen <git@vexu.eu>2022-08-17 20:10:18 +0300
commitdb0f372da8b25f4a911cd8e0b7f8e5cdfc64f940 (patch)
tree1258577ea70114ad891b917d25eecc0cf958d19b /src/Sema.zig
parenta12abc6d6c8b89a09befdcbd9019247ccc3bd641 (diff)
downloadzig-db0f372da8b25f4a911cd8e0b7f8e5cdfc64f940.tar.gz
zig-db0f372da8b25f4a911cd8e0b7f8e5cdfc64f940.zip
Sema: make optional noreturn behave correctly
Diffstat (limited to 'src/Sema.zig')
-rw-r--r--src/Sema.zig15
1 files changed, 13 insertions, 2 deletions
diff --git a/src/Sema.zig b/src/Sema.zig
index d7d6994bcd..ceeb8af23c 100644
--- a/src/Sema.zig
+++ b/src/Sema.zig
@@ -6684,8 +6684,13 @@ fn zirOptionalType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
defer tracy.end();
const inst_data = sema.code.instructions.items(.data)[inst].un_node;
- const src = inst_data.src();
- const child_type = try sema.resolveType(block, src, inst_data.operand);
+ const operand_src: LazySrcLoc = .{ .node_offset_un_op = inst_data.src_node };
+ const child_type = try sema.resolveType(block, operand_src, inst_data.operand);
+ if (child_type.zigTypeTag() == .Opaque) {
+ return sema.fail(block, operand_src, "opaque type '{}' cannot be optional", .{child_type.fmt(sema.mod)});
+ } else if (child_type.zigTypeTag() == .Null) {
+ return sema.fail(block, operand_src, "type '{}' cannot be optional", .{child_type.fmt(sema.mod)});
+ }
const opt_type = try Type.optional(sema.arena, child_type);
return sema.addType(opt_type);
@@ -25714,6 +25719,12 @@ fn analyzeIsNull(
return Air.Inst.Ref.bool_false;
}
}
+
+ const operand_ty = sema.typeOf(operand);
+ var buf: Type.Payload.ElemType = undefined;
+ if (operand_ty.zigTypeTag() == .Optional and operand_ty.optionalChild(&buf).zigTypeTag() == .NoReturn) {
+ return Air.Inst.Ref.bool_true;
+ }
try sema.requireRuntimeBlock(block, src, null);
const air_tag: Air.Inst.Tag = if (invert_logic) .is_non_null else .is_null;
return block.addUnOp(air_tag, operand);