Commit 58caed1c71
Changed files (5)
src
test
cases
compile_errors
src/link/MachO/load_commands.zig
@@ -36,7 +36,7 @@ fn calcLCsSize(gpa: Allocator, options: *const link.Options, ctx: CalcLCsSizeCtx
// LC_DYLD_INFO_ONLY
sizeofcmds += @sizeOf(macho.dyld_info_command);
// LC_FUNCTION_STARTS
- if (has_text_segment and ctx.wants_function_starts) |_| {
+ if (has_text_segment and ctx.wants_function_starts) {
sizeofcmds += @sizeOf(macho.linkedit_data_command);
}
// LC_DATA_IN_CODE
src/AstGen.zig
@@ -6071,7 +6071,7 @@ fn whileExpr(
const tag: Zir.Inst.Tag = if (payload_is_ref) .is_non_err_ptr else .is_non_err;
break :c .{
.inst = err_union,
- .bool_bit = try cond_scope.addUnNode(tag, err_union, while_full.ast.then_expr),
+ .bool_bit = try cond_scope.addUnNode(tag, err_union, while_full.ast.cond_expr),
};
} else if (while_full.payload_token) |_| {
const cond_ri: ResultInfo = .{ .rl = if (payload_is_ref) .ref else .none };
@@ -6079,7 +6079,7 @@ fn whileExpr(
const tag: Zir.Inst.Tag = if (payload_is_ref) .is_non_null_ptr else .is_non_null;
break :c .{
.inst = optional,
- .bool_bit = try cond_scope.addUnNode(tag, optional, while_full.ast.then_expr),
+ .bool_bit = try cond_scope.addUnNode(tag, optional, while_full.ast.cond_expr),
};
} else {
const cond = try expr(&cond_scope, &cond_scope.base, bool_ri, while_full.ast.cond_expr);
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);
}
test/cases/compile_errors/stage1/obj/invalid_maybe_type.zig
@@ -1,9 +0,0 @@
-export fn f() void {
- if (true) |x| { _ = x; }
-}
-
-// error
-// backend=stage1
-// target=native
-//
-// tmp.zig:2:9: error: expected optional type, found 'bool'
test/cases/compile_errors/invalid_capture_type.zig
@@ -0,0 +1,24 @@
+export fn f1() void {
+ if (true) |x| { _ = x; }
+}
+export fn f2() void {
+ if (@as(usize, 5)) |_| {}
+}
+export fn f3() void {
+ if (@as(usize, 5)) |_| {} else |_| {}
+}
+export fn f4() void {
+ if (null) |_| {}
+}
+export fn f5() void {
+ if (error.Foo) |_| {} else |_| {}
+}
+
+// error
+// backend=stage2
+// target=native
+//
+// :2:9: error: expected optional type, found 'bool'
+// :5:9: error: expected optional type, found 'usize'
+// :8:9: error: expected error union type, found 'usize'
+// :14:9: error: expected error union type, found 'error{Foo}'