aboutsummaryrefslogtreecommitdiff
path: root/src/Sema.zig
diff options
context:
space:
mode:
authorVeikka Tuominen <git@vexu.eu>2022-12-15 21:18:42 +0200
committerVeikka Tuominen <git@vexu.eu>2022-12-17 13:22:09 +0200
commit58caed1c71179f48c4e7bffadef0392fa8381e72 (patch)
tree7dec9c4a86979d129d824ac3124054d89eb1c849 /src/Sema.zig
parent90477e5c10c9c263a3c0038e1ae7b814d2c5397e (diff)
downloadzig-58caed1c71179f48c4e7bffadef0392fa8381e72.tar.gz
zig-58caed1c71179f48c4e7bffadef0392fa8381e72.zip
Sema: make is_non_{null,err} stricter about types
Closes #13023
Diffstat (limited to 'src/Sema.zig')
-rw-r--r--src/Sema.zig23
1 files changed, 23 insertions, 0 deletions
diff --git a/src/Sema.zig b/src/Sema.zig
index e67965271a..0a7496f730 100644
--- a/src/Sema.zig
+++ b/src/Sema.zig
@@ -16356,6 +16356,15 @@ fn finishCondBr(
return Air.indexToRef(block_inst);
}
+fn checkNullableType(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !void {
+ switch (ty.zigTypeTag()) {
+ .Optional, .Null, .Undefined => return,
+ .Pointer => if (ty.isPtrLikeOptional()) return,
+ else => {},
+ }
+ return sema.failWithExpectedOptionalType(block, src, ty);
+}
+
fn zirIsNonNull(
sema: *Sema,
block: *Block,
@@ -16367,6 +16376,7 @@ fn zirIsNonNull(
const inst_data = sema.code.instructions.items(.data)[inst].un_node;
const src = inst_data.src();
const operand = try sema.resolveInst(inst_data.operand);
+ try sema.checkNullableType(block, src, sema.typeOf(operand));
return sema.analyzeIsNull(block, src, operand, true);
}
@@ -16381,6 +16391,7 @@ fn zirIsNonNullPtr(
const inst_data = sema.code.instructions.items(.data)[inst].un_node;
const src = inst_data.src();
const ptr = try sema.resolveInst(inst_data.operand);
+ try sema.checkNullableType(block, src, sema.typeOf(ptr).elemType2());
if ((try sema.resolveMaybeUndefVal(ptr)) == null) {
return block.addUnOp(.is_non_null_ptr, ptr);
}
@@ -16388,12 +16399,23 @@ fn zirIsNonNullPtr(
return sema.analyzeIsNull(block, src, loaded, true);
}
+fn checkErrorType(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !void {
+ switch (ty.zigTypeTag()) {
+ .ErrorSet, .ErrorUnion, .Undefined => return,
+ else => return sema.fail(block, src, "expected error union type, found '{}'", .{
+ ty.fmt(sema.mod),
+ }),
+ }
+}
+
fn zirIsNonErr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
const tracy = trace(@src());
defer tracy.end();
const inst_data = sema.code.instructions.items(.data)[inst].un_node;
+ const src = inst_data.src();
const operand = try sema.resolveInst(inst_data.operand);
+ try sema.checkErrorType(block, src, sema.typeOf(operand));
return sema.analyzeIsNonErr(block, inst_data.src(), operand);
}
@@ -16404,6 +16426,7 @@ fn zirIsNonErrPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
const inst_data = sema.code.instructions.items(.data)[inst].un_node;
const src = inst_data.src();
const ptr = try sema.resolveInst(inst_data.operand);
+ try sema.checkErrorType(block, src, sema.typeOf(ptr).elemType2());
const loaded = try sema.analyzeLoad(block, src, ptr, src);
return sema.analyzeIsNonErr(block, src, loaded);
}