authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-11-26 22:03:49+02:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2022-11-26 22:03:49+02:00
log304e828088f0b03d47f7b0b3df7b1449c0a1f2d6
treea048ea78944632c0d088e9316e468ad0af21340c
parentf61c5f3f5242fb3e96891c82eb3dd16fdb8a2c7b
parent71937f75d83d960e0ec61eb697e4e3420685f9ca
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #13637 from Vexu/stage2-fixes

Stage2 bug fixes

7 files changed, 310 insertions(+), 50 deletions(-)

src/AstGen.zig+3
...@@ -7717,6 +7717,7 @@ fn typeOf(...@@ -7717,6 +7717,7 @@ fn typeOf(
77177717
7718 var typeof_scope = gz.makeSubBlock(scope);7718 var typeof_scope = gz.makeSubBlock(scope);
7719 typeof_scope.force_comptime = false;7719 typeof_scope.force_comptime = false;
7720 typeof_scope.c_import = false;
7720 defer typeof_scope.unstack();7721 defer typeof_scope.unstack();
77217722
7722 const ty_expr = try reachableExpr(&typeof_scope, &typeof_scope.base, .{ .rl = .none }, args[0], node);7723 const ty_expr = try reachableExpr(&typeof_scope, &typeof_scope.base, .{ .rl = .none }, args[0], node);
...@@ -8575,6 +8576,8 @@ fn cImport(...@@ -8575,6 +8576,8 @@ fn cImport(
8575 const astgen = gz.astgen;8576 const astgen = gz.astgen;
8576 const gpa = astgen.gpa;8577 const gpa = astgen.gpa;
85778578
8579 if (gz.c_import) return gz.astgen.failNode(node, "cannot nest @cImport", .{});
8580
8578 var block_scope = gz.makeSubBlock(scope);8581 var block_scope = gz.makeSubBlock(scope);
8579 block_scope.force_comptime = true;8582 block_scope.force_comptime = true;
8580 block_scope.c_import = true;8583 block_scope.c_import = true;
src/Sema.zig+215-33
...@@ -5105,6 +5105,7 @@ fn zirBlock(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileErro...@@ -5105,6 +5105,7 @@ fn zirBlock(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileErro
5105 .is_typeof = parent_block.is_typeof,5105 .is_typeof = parent_block.is_typeof,
5106 .want_safety = parent_block.want_safety,5106 .want_safety = parent_block.want_safety,
5107 .float_mode = parent_block.float_mode,5107 .float_mode = parent_block.float_mode,
5108 .c_import_buf = parent_block.c_import_buf,
5108 .runtime_cond = parent_block.runtime_cond,5109 .runtime_cond = parent_block.runtime_cond,
5109 .runtime_loop = parent_block.runtime_loop,5110 .runtime_loop = parent_block.runtime_loop,
5110 .runtime_index = parent_block.runtime_index,5111 .runtime_index = parent_block.runtime_index,
...@@ -7031,16 +7032,21 @@ fn instantiateGenericCall(...@@ -7031,16 +7032,21 @@ fn instantiateGenericCall(
7031 }7032 }
7032 const arg = uncasted_args[arg_i];7033 const arg = uncasted_args[arg_i];
7033 if (is_comptime) {7034 if (is_comptime) {
7034 if (try sema.resolveMaybeUndefVal(arg)) |arg_val| {7035 const arg_val = (try sema.resolveMaybeUndefVal(arg)).?;
7035 const child_arg = try child_sema.addConstant(sema.typeOf(arg), arg_val);7036 const child_arg = try child_sema.addConstant(sema.typeOf(arg), arg_val);
7036 child_sema.inst_map.putAssumeCapacityNoClobber(inst, child_arg);7037 child_sema.inst_map.putAssumeCapacityNoClobber(inst, child_arg);
7037 } else {
7038 return sema.failWithNeededComptime(block, .unneeded, "");
7039 }
7040 } else if (is_anytype) {7038 } else if (is_anytype) {
7041 const arg_ty = sema.typeOf(arg);7039 const arg_ty = sema.typeOf(arg);
7042 if (try sema.typeRequiresComptime(arg_ty)) {7040 if (try sema.typeRequiresComptime(arg_ty)) {
7043 const arg_val = try sema.resolveConstValue(block, .unneeded, arg, "");7041 const arg_val = sema.resolveConstValue(block, .unneeded, arg, "") catch |err| switch (err) {
7042 error.NeededSourceLocation => {
7043 const decl = sema.mod.declPtr(block.src_decl);
7044 const arg_src = Module.argSrc(call_src.node_offset.x, sema.gpa, decl, arg_i, bound_arg_src);
7045 _ = try sema.resolveConstValue(block, arg_src, arg, "argument to parameter with comptime-only type must be comptime-known");
7046 return error.AnalysisFail;
7047 },
7048 else => |e| return e,
7049 };
7044 const child_arg = try child_sema.addConstant(arg_ty, arg_val);7050 const child_arg = try child_sema.addConstant(arg_ty, arg_val);
7045 child_sema.inst_map.putAssumeCapacityNoClobber(inst, child_arg);7051 child_sema.inst_map.putAssumeCapacityNoClobber(inst, child_arg);
7046 } else {7052 } else {
...@@ -7575,7 +7581,8 @@ fn zirEnumToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -7575,7 +7581,8 @@ fn zirEnumToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
7575 const enum_tag: Air.Inst.Ref = switch (operand_ty.zigTypeTag()) {7581 const enum_tag: Air.Inst.Ref = switch (operand_ty.zigTypeTag()) {
7576 .Enum => operand,7582 .Enum => operand,
7577 .Union => blk: {7583 .Union => blk: {
7578 const tag_ty = operand_ty.unionTagType() orelse {7584 const union_ty = try sema.resolveTypeFields(operand_ty);
7585 const tag_ty = union_ty.unionTagType() orelse {
7579 return sema.fail(7586 return sema.fail(
7580 block,7587 block,
7581 operand_src,7588 operand_src,
...@@ -9691,10 +9698,12 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -9691,10 +9698,12 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
9691 };9698 };
96929699
9693 const maybe_union_ty = blk: {9700 const maybe_union_ty = blk: {
9701 const zir_tags = sema.code.instructions.items(.tag);
9694 const zir_data = sema.code.instructions.items(.data);9702 const zir_data = sema.code.instructions.items(.data);
9695 const cond_index = Zir.refToIndex(extra.data.operand).?;9703 const cond_index = Zir.refToIndex(extra.data.operand).?;
9696 const raw_operand = sema.resolveInst(zir_data[cond_index].un_node.operand) catch unreachable;9704 const raw_operand = sema.resolveInst(zir_data[cond_index].un_node.operand) catch unreachable;
9697 break :blk sema.typeOf(raw_operand);9705 const target_ty = sema.typeOf(raw_operand);
9706 break :blk if (zir_tags[cond_index] == .switch_cond_ref) target_ty.elemType() else target_ty;
9698 };9707 };
9699 const union_originally = maybe_union_ty.zigTypeTag() == .Union;9708 const union_originally = maybe_union_ty.zigTypeTag() == .Union;
97009709
...@@ -10260,6 +10269,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -10260,6 +10269,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
10260 .comptime_reason = block.comptime_reason,10269 .comptime_reason = block.comptime_reason,
10261 .is_typeof = block.is_typeof,10270 .is_typeof = block.is_typeof,
10262 .switch_else_err_ty = else_error_ty,10271 .switch_else_err_ty = else_error_ty,
10272 .c_import_buf = block.c_import_buf,
10263 .runtime_cond = block.runtime_cond,10273 .runtime_cond = block.runtime_cond,
10264 .runtime_loop = block.runtime_loop,10274 .runtime_loop = block.runtime_loop,
10265 .runtime_index = block.runtime_index,10275 .runtime_index = block.runtime_index,
...@@ -13479,7 +13489,6 @@ fn zirOverflowArithmetic(...@@ -13479,7 +13489,6 @@ fn zirOverflowArithmetic(
13479 const maybe_rhs_val = try sema.resolveMaybeUndefVal(rhs);13489 const maybe_rhs_val = try sema.resolveMaybeUndefVal(rhs);
1348013490
13481 const tuple_ty = try sema.overflowArithmeticTupleType(dest_ty);13491 const tuple_ty = try sema.overflowArithmeticTupleType(dest_ty);
13482 const ov_ty = tuple_ty.tupleFields().types[1];
13483 // TODO: Remove and use `ov_ty` instead.13492 // TODO: Remove and use `ov_ty` instead.
13484 // This is a temporary type used until overflow arithmetic properly returns `u1` instead of `bool`.13493 // This is a temporary type used until overflow arithmetic properly returns `u1` instead of `bool`.
13485 const overflowed_ty = if (dest_ty.zigTypeTag() == .Vector) try Type.vector(sema.arena, dest_ty.vectorLen(), Type.bool) else Type.bool;13494 const overflowed_ty = if (dest_ty.zigTypeTag() == .Vector) try Type.vector(sema.arena, dest_ty.vectorLen(), Type.bool) else Type.bool;
...@@ -13630,14 +13639,7 @@ fn zirOverflowArithmetic(...@@ -13630,14 +13639,7 @@ fn zirOverflowArithmetic(
13630 try sema.storePtr2(block, src, ptr, ptr_src, wrapped, src, .store);13639 try sema.storePtr2(block, src, ptr, ptr_src, wrapped, src, .store);
1363113640
13632 const overflow_bit = try sema.tupleFieldValByIndex(block, src, tuple, 1, tuple_ty);13641 const overflow_bit = try sema.tupleFieldValByIndex(block, src, tuple, 1, tuple_ty);
13633 const zero_ov_val = if (dest_ty.zigTypeTag() == .Vector) try Value.Tag.repeated.create(sema.arena, Value.zero) else Value.zero;13642 return block.addBitCast(overflowed_ty, overflow_bit);
13634 const zero_ov = try sema.addConstant(ov_ty, zero_ov_val);
13635
13636 const overflowed_inst = if (dest_ty.zigTypeTag() == .Vector)
13637 block.addCmpVector(overflow_bit, .zero, .neq, try sema.addType(ov_ty))
13638 else
13639 block.addBinOp(.cmp_neq, overflow_bit, zero_ov);
13640 return overflowed_inst;
13641 };13643 };
1364213644
13643 try sema.storePtr2(block, src, ptr, ptr_src, result.wrapped, src, .store);13645 try sema.storePtr2(block, src, ptr, ptr_src, result.wrapped, src, .store);
...@@ -22675,7 +22677,8 @@ fn fieldPtr(...@@ -22675,7 +22677,8 @@ fn fieldPtr(
22675 return inst;22677 return inst;
22676 }22678 }
22677 }22679 }
22678 if (child_type.unionTagType()) |enum_ty| {22680 const union_ty = try sema.resolveTypeFields(child_type);
22681 if (union_ty.unionTagType()) |enum_ty| {
22679 if (enum_ty.enumFieldIndex(field_name)) |field_index| {22682 if (enum_ty.enumFieldIndex(field_name)) |field_index| {
22680 const field_index_u32 = @intCast(u32, field_index);22683 const field_index_u32 = @intCast(u32, field_index);
22681 var anon_decl = try block.startAnonDecl();22684 var anon_decl = try block.startAnonDecl();
...@@ -29101,20 +29104,7 @@ fn resolveStructLayout(sema: *Sema, ty: Type) CompileError!void {...@@ -29101,20 +29104,7 @@ fn resolveStructLayout(sema: *Sema, ty: Type) CompileError!void {
29101 }29104 }
2910229105
29103 struct_obj.status = .have_layout;29106 struct_obj.status = .have_layout;
2910429107 _ = try sema.resolveTypeRequiresComptime(resolved_ty);
29105 // In case of querying the ABI alignment of this struct, we will ask
29106 // for hasRuntimeBits() of each field, so we need "requires comptime"
29107 // to be known already before this function returns.
29108 for (struct_obj.fields.values()) |field, i| {
29109 _ = sema.typeRequiresComptime(field.ty) catch |err| switch (err) {
29110 error.AnalysisFail => {
29111 const msg = sema.err orelse return err;
29112 try sema.addFieldErrNote(ty, i, msg, "while checking this field", .{});
29113 return err;
29114 },
29115 else => return err,
29116 };
29117 }
29118 }29108 }
29119 // otherwise it's a tuple; no need to resolve anything29109 // otherwise it's a tuple; no need to resolve anything
29120}29110}
...@@ -29278,6 +29268,198 @@ fn resolveUnionLayout(sema: *Sema, ty: Type) CompileError!void {...@@ -29278,6 +29268,198 @@ fn resolveUnionLayout(sema: *Sema, ty: Type) CompileError!void {
29278 };29268 };
29279 }29269 }
29280 union_obj.status = .have_layout;29270 union_obj.status = .have_layout;
29271 _ = try sema.resolveTypeRequiresComptime(resolved_ty);
29272}
29273
29274// In case of querying the ABI alignment of this struct, we will ask
29275// for hasRuntimeBits() of each field, so we need "requires comptime"
29276// to be known already before this function returns.
29277pub fn resolveTypeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {
29278 return switch (ty.tag()) {
29279 .u1,
29280 .u8,
29281 .i8,
29282 .u16,
29283 .i16,
29284 .u29,
29285 .u32,
29286 .i32,
29287 .u64,
29288 .i64,
29289 .u128,
29290 .i128,
29291 .usize,
29292 .isize,
29293 .c_short,
29294 .c_ushort,
29295 .c_int,
29296 .c_uint,
29297 .c_long,
29298 .c_ulong,
29299 .c_longlong,
29300 .c_ulonglong,
29301 .c_longdouble,
29302 .f16,
29303 .f32,
29304 .f64,
29305 .f80,
29306 .f128,
29307 .anyopaque,
29308 .bool,
29309 .void,
29310 .anyerror,
29311 .noreturn,
29312 .@"anyframe",
29313 .null,
29314 .undefined,
29315 .atomic_order,
29316 .atomic_rmw_op,
29317 .calling_convention,
29318 .address_space,
29319 .float_mode,
29320 .reduce_op,
29321 .call_options,
29322 .prefetch_options,
29323 .export_options,
29324 .extern_options,
29325 .manyptr_u8,
29326 .manyptr_const_u8,
29327 .manyptr_const_u8_sentinel_0,
29328 .const_slice_u8,
29329 .const_slice_u8_sentinel_0,
29330 .anyerror_void_error_union,
29331 .empty_struct_literal,
29332 .empty_struct,
29333 .error_set,
29334 .error_set_single,
29335 .error_set_inferred,
29336 .error_set_merged,
29337 .@"opaque",
29338 .generic_poison,
29339 .array_u8,
29340 .array_u8_sentinel_0,
29341 .int_signed,
29342 .int_unsigned,
29343 .enum_simple,
29344 => false,
29345
29346 .single_const_pointer_to_comptime_int,
29347 .type,
29348 .comptime_int,
29349 .comptime_float,
29350 .enum_literal,
29351 .type_info,
29352 // These are function bodies, not function pointers.
29353 .fn_noreturn_no_args,
29354 .fn_void_no_args,
29355 .fn_naked_noreturn_no_args,
29356 .fn_ccc_void_no_args,
29357 .function,
29358 => true,
29359
29360 .var_args_param => unreachable,
29361 .inferred_alloc_mut => unreachable,
29362 .inferred_alloc_const => unreachable,
29363 .bound_fn => unreachable,
29364
29365 .array,
29366 .array_sentinel,
29367 .vector,
29368 => return sema.resolveTypeRequiresComptime(ty.childType()),
29369
29370 .pointer,
29371 .single_const_pointer,
29372 .single_mut_pointer,
29373 .many_const_pointer,
29374 .many_mut_pointer,
29375 .c_const_pointer,
29376 .c_mut_pointer,
29377 .const_slice,
29378 .mut_slice,
29379 => {
29380 const child_ty = ty.childType();
29381 if (child_ty.zigTypeTag() == .Fn) {
29382 return child_ty.fnInfo().is_generic;
29383 } else {
29384 return sema.resolveTypeRequiresComptime(child_ty);
29385 }
29386 },
29387
29388 .optional,
29389 .optional_single_mut_pointer,
29390 .optional_single_const_pointer,
29391 => {
29392 var buf: Type.Payload.ElemType = undefined;
29393 return sema.resolveTypeRequiresComptime(ty.optionalChild(&buf));
29394 },
29395
29396 .tuple, .anon_struct => {
29397 const tuple = ty.tupleFields();
29398 for (tuple.types) |field_ty, i| {
29399 const have_comptime_val = tuple.values[i].tag() != .unreachable_value;
29400 if (!have_comptime_val and try sema.resolveTypeRequiresComptime(field_ty)) {
29401 return true;
29402 }
29403 }
29404 return false;
29405 },
29406
29407 .@"struct" => {
29408 const struct_obj = ty.castTag(.@"struct").?.data;
29409 switch (struct_obj.requires_comptime) {
29410 .no, .wip => return false,
29411 .yes => return true,
29412 .unknown => {
29413 var requires_comptime = false;
29414 struct_obj.requires_comptime = .wip;
29415 for (struct_obj.fields.values()) |field| {
29416 if (try sema.resolveTypeRequiresComptime(field.ty)) requires_comptime = true;
29417 }
29418 if (requires_comptime) {
29419 struct_obj.requires_comptime = .yes;
29420 } else {
29421 struct_obj.requires_comptime = .no;
29422 }
29423 return requires_comptime;
29424 },
29425 }
29426 },
29427
29428 .@"union", .union_safety_tagged, .union_tagged => {
29429 const union_obj = ty.cast(Type.Payload.Union).?.data;
29430 switch (union_obj.requires_comptime) {
29431 .no, .wip => return false,
29432 .yes => return true,
29433 .unknown => {
29434 var requires_comptime = false;
29435 union_obj.requires_comptime = .wip;
29436 for (union_obj.fields.values()) |field| {
29437 if (try sema.resolveTypeRequiresComptime(field.ty)) requires_comptime = true;
29438 }
29439 if (requires_comptime) {
29440 union_obj.requires_comptime = .yes;
29441 } else {
29442 union_obj.requires_comptime = .no;
29443 }
29444 return requires_comptime;
29445 },
29446 }
29447 },
29448
29449 .error_union => return sema.resolveTypeRequiresComptime(ty.errorUnionPayload()),
29450 .anyframe_T => {
29451 const child_ty = ty.castTag(.anyframe_T).?.data;
29452 return sema.resolveTypeRequiresComptime(child_ty);
29453 },
29454 .enum_numbered => {
29455 const tag_ty = ty.castTag(.enum_numbered).?.data.tag_ty;
29456 return sema.resolveTypeRequiresComptime(tag_ty);
29457 },
29458 .enum_full, .enum_nonexhaustive => {
29459 const tag_ty = ty.cast(Type.Payload.EnumFull).?.data.tag_ty;
29460 return sema.resolveTypeRequiresComptime(tag_ty);
29461 },
29462 };
29281}29463}
2928229464
29283/// Returns `error.AnalysisFail` if any of the types (recursively) failed to29465/// Returns `error.AnalysisFail` if any of the types (recursively) failed to
test/behavior/union.zig+8-1
...@@ -1287,7 +1287,14 @@ test "noreturn field in union" {...@@ -1287,7 +1287,14 @@ test "noreturn field in union" {
1287 try expect(a == .a);1287 try expect(a == .a);
1288 },1288 },
1289 }1289 }
1290 try expect(count == 5);1290 switch (a) {
1291 .a => count += 1,
1292 .b, .c => |*val| {
1293 _ = val;
1294 @compileError("bad");
1295 },
1296 }
1297 try expect(count == 6);
1291}1298}
12921299
1293test "union and enum field order doesn't match" {1300test "union and enum field order doesn't match" {
test/behavior/vector.zig+33-16
...@@ -977,27 +977,35 @@ test "@addWithOverflow" {...@@ -977,27 +977,35 @@ test "@addWithOverflow" {
977 fn doTheTest() !void {977 fn doTheTest() !void {
978 {978 {
979 var result: @Vector(4, u8) = undefined;979 var result: @Vector(4, u8) = undefined;
980 var overflow = @addWithOverflow(@Vector(4, u8), @Vector(4, u8){ 250, 250, 250, 250 }, @Vector(4, u8){ 0, 5, 6, 10 }, &result);980 var lhs = @Vector(4, u8){ 250, 250, 250, 250 };
981 var rhs = @Vector(4, u8){ 0, 5, 6, 10 };
982 var overflow = @addWithOverflow(@Vector(4, u8), lhs, rhs, &result);
981 var expected: @Vector(4, bool) = .{ false, false, true, true };983 var expected: @Vector(4, bool) = .{ false, false, true, true };
982 try expect(mem.eql(bool, &@as([4]bool, overflow), &@as([4]bool, expected)));984 try expectEqual(expected, overflow);
983 }985 }
984 {986 {
985 var result: @Vector(4, i8) = undefined;987 var result: @Vector(4, i8) = undefined;
986 var overflow = @addWithOverflow(@Vector(4, i8), @Vector(4, i8){ -125, -125, 125, 125 }, @Vector(4, i8){ -3, -4, 2, 3 }, &result);988 var lhs = @Vector(4, i8){ -125, -125, 125, 125 };
989 var rhs = @Vector(4, i8){ -3, -4, 2, 3 };
990 var overflow = @addWithOverflow(@Vector(4, i8), lhs, rhs, &result);
987 var expected: @Vector(4, bool) = .{ false, true, false, true };991 var expected: @Vector(4, bool) = .{ false, true, false, true };
988 try expect(mem.eql(bool, &@as([4]bool, overflow), &@as([4]bool, expected)));992 try expectEqual(expected, overflow);
989 }993 }
990 {994 {
991 var result: @Vector(4, u1) = undefined;995 var result: @Vector(4, u1) = undefined;
992 var overflow = @addWithOverflow(@Vector(4, u1), @Vector(4, u1){ 0, 0, 1, 1 }, @Vector(4, u1){ 0, 1, 0, 1 }, &result);996 var lhs = @Vector(4, u1){ 0, 0, 1, 1 };
997 var rhs = @Vector(4, u1){ 0, 1, 0, 1 };
998 var overflow = @addWithOverflow(@Vector(4, u1), lhs, rhs, &result);
993 var expected: @Vector(4, bool) = .{ false, false, false, true };999 var expected: @Vector(4, bool) = .{ false, false, false, true };
994 try expect(mem.eql(bool, &@as([4]bool, overflow), &@as([4]bool, expected)));1000 try expectEqual(expected, overflow);
995 }1001 }
996 {1002 {
997 var result: @Vector(4, u0) = undefined;1003 var result: @Vector(4, u0) = undefined;
998 var overflow = @addWithOverflow(@Vector(4, u0), @Vector(4, u0){ 0, 0, 0, 0 }, @Vector(4, u0){ 0, 0, 0, 0 }, &result);1004 var lhs = @Vector(4, u0){ 0, 0, 0, 0 };
1005 var rhs = @Vector(4, u0){ 0, 0, 0, 0 };
1006 var overflow = @addWithOverflow(@Vector(4, u0), lhs, rhs, &result);
999 var expected: @Vector(4, bool) = .{ false, false, false, false };1007 var expected: @Vector(4, bool) = .{ false, false, false, false };
1000 try expect(mem.eql(bool, &@as([4]bool, overflow), &@as([4]bool, expected)));1008 try expectEqual(expected, overflow);
1001 }1009 }
1002 }1010 }
1003 };1011 };
...@@ -1019,15 +1027,19 @@ test "@subWithOverflow" {...@@ -1019,15 +1027,19 @@ test "@subWithOverflow" {
1019 fn doTheTest() !void {1027 fn doTheTest() !void {
1020 {1028 {
1021 var result: @Vector(2, u8) = undefined;1029 var result: @Vector(2, u8) = undefined;
1022 var overflow = @subWithOverflow(@Vector(2, u8), @Vector(2, u8){ 5, 5 }, @Vector(2, u8){ 5, 6 }, &result);1030 var lhs = @Vector(2, u8){ 5, 5 };
1031 var rhs = @Vector(2, u8){ 5, 6 };
1032 var overflow = @subWithOverflow(@Vector(2, u8), lhs, rhs, &result);
1023 var expected: @Vector(2, bool) = .{ false, true };1033 var expected: @Vector(2, bool) = .{ false, true };
1024 try expect(mem.eql(bool, &@as([2]bool, overflow), &@as([2]bool, expected)));1034 try expectEqual(expected, overflow);
1025 }1035 }
1026 {1036 {
1027 var result: @Vector(4, i8) = undefined;1037 var result: @Vector(4, i8) = undefined;
1028 var overflow = @subWithOverflow(@Vector(4, i8), @Vector(4, i8){ -120, -120, 120, 120 }, @Vector(4, i8){ 8, 9, -7, -8 }, &result);1038 var lhs = @Vector(4, i8){ -120, -120, 120, 120 };
1039 var rhs = @Vector(4, i8){ 8, 9, -7, -8 };
1040 var overflow = @subWithOverflow(@Vector(4, i8), lhs, rhs, &result);
1029 var expected: @Vector(4, bool) = .{ false, true, false, true };1041 var expected: @Vector(4, bool) = .{ false, true, false, true };
1030 try expect(mem.eql(bool, &@as([4]bool, overflow), &@as([4]bool, expected)));1042 try expectEqual(expected, overflow);
1031 }1043 }
1032 }1044 }
1033 };1045 };
...@@ -1048,9 +1060,11 @@ test "@mulWithOverflow" {...@@ -1048,9 +1060,11 @@ test "@mulWithOverflow" {
1048 const S = struct {1060 const S = struct {
1049 fn doTheTest() !void {1061 fn doTheTest() !void {
1050 var result: @Vector(4, u8) = undefined;1062 var result: @Vector(4, u8) = undefined;
1051 var overflow = @mulWithOverflow(@Vector(4, u8), @Vector(4, u8){ 10, 10, 10, 10 }, @Vector(4, u8){ 25, 26, 0, 30 }, &result);1063 var lhs = @Vector(4, u8){ 10, 10, 10, 10 };
1064 var rhs = @Vector(4, u8){ 25, 26, 0, 30 };
1065 var overflow = @mulWithOverflow(@Vector(4, u8), lhs, rhs, &result);
1052 var expected: @Vector(4, bool) = .{ false, true, false, true };1066 var expected: @Vector(4, bool) = .{ false, true, false, true };
1053 try expect(mem.eql(bool, &@as([4]bool, overflow), &@as([4]bool, expected)));1067 try expectEqual(expected, overflow);
1054 }1068 }
1055 };1069 };
1056 try S.doTheTest();1070 try S.doTheTest();
...@@ -1062,6 +1076,7 @@ test "@shlWithOverflow" {...@@ -1062,6 +1076,7 @@ test "@shlWithOverflow" {
1062 // stage1 doesn't support vector args1076 // stage1 doesn't support vector args
1063 return error.SkipZigTest;1077 return error.SkipZigTest;
1064 }1078 }
1079 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
1065 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO1080 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
1066 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO1081 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
1067 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1082 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
...@@ -1070,9 +1085,11 @@ test "@shlWithOverflow" {...@@ -1070,9 +1085,11 @@ test "@shlWithOverflow" {
1070 const S = struct {1085 const S = struct {
1071 fn doTheTest() !void {1086 fn doTheTest() !void {
1072 var result: @Vector(4, u8) = undefined;1087 var result: @Vector(4, u8) = undefined;
1073 var overflow = @shlWithOverflow(@Vector(4, u8), @Vector(4, u8){ 0, 1, 8, 255 }, @Vector(4, u3){ 7, 7, 7, 7 }, &result);1088 var lhs = @Vector(4, u8){ 0, 1, 8, 255 };
1089 var rhs = @Vector(4, u3){ 7, 7, 7, 7 };
1090 var overflow = @shlWithOverflow(@Vector(4, u8), lhs, rhs, &result);
1074 var expected: @Vector(4, bool) = .{ false, false, true, true };1091 var expected: @Vector(4, bool) = .{ false, false, true, true };
1075 try expect(mem.eql(bool, &@as([4]bool, overflow), &@as([4]bool, expected)));1092 try expectEqual(expected, overflow);
1076 }1093 }
1077 };1094 };
1078 try S.doTheTest();1095 try S.doTheTest();
test/cases/compile_errors/anytype_param_requires_comptime.zig created+20
...@@ -0,0 +1,20 @@
1const S = struct {
2 fn foo(b: u32, c: anytype) void {
3 const C = struct {
4 c: @TypeOf(c),
5 b: u32,
6 };
7 bar(C{ .c = c, .b = b });
8 }
9 fn bar(_: anytype) void {}
10};
11pub export fn entry() void {
12 S.foo(0, u32);
13}
14
15// error
16// backend=stage2
17// target=native
18//
19// :7:14: error: unable to resolve comptime value
20// :7:14: note: argument to parameter with comptime-only type must be comptime-known
test/cases/compile_errors/cimport.zig created+15
...@@ -0,0 +1,15 @@
1const b = @cDefine("foo", "1");
2const c = @cImport({
3 _ = @TypeOf(@cDefine("foo", "1"));
4});
5const d = @cImport({
6 _ = @cImport(@cDefine("foo", "1"));
7});
8
9// error
10// backend=stage2
11// target=native
12//
13// :1:11: error: C define valid only inside C import block
14// :3:17: error: C define valid only inside C import block
15// :6:9: error: cannot nest @cImport
test/cases/compile_errors/union_fields_are_resolved_before_tag_type_is_needed.zig created+16
...@@ -0,0 +1,16 @@
1const T = union(enum) {
2 a,
3 pub fn f(self: T) void {
4 _ = self;
5 }
6};
7pub export fn entry() void {
8 T.a.f();
9}
10
11// error
12// backend=stage2
13// target=native
14//
15// :8:8: error: no field or member function named 'f' in '@typeInfo(tmp.T).Union.tag_type.?'
16// :1:11: note: enum declared here