authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-11-26 22:03:49+02:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-01-09 14:42:52-07:00
logb75197ef88f3d9fa6c7022a7f1a48f69218d4492
tree61b704d950647c6504f4fa57331cd80e1bd42ba0
parentddfcf0246e8d464f921ee70e5a54fa75c3b4d94b

Merge pull request #13637 from Vexu/stage2-fixes

Stage2 bug fixes

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

src/AstGen.zig+3
...@@ -7693,6 +7693,7 @@ fn typeOf(...@@ -7693,6 +7693,7 @@ fn typeOf(
76937693
7694 var typeof_scope = gz.makeSubBlock(scope);7694 var typeof_scope = gz.makeSubBlock(scope);
7695 typeof_scope.force_comptime = false;7695 typeof_scope.force_comptime = false;
7696 typeof_scope.c_import = false;
7696 defer typeof_scope.unstack();7697 defer typeof_scope.unstack();
76977698
7698 const ty_expr = try reachableExpr(&typeof_scope, &typeof_scope.base, .{ .rl = .none }, args[0], node);7699 const ty_expr = try reachableExpr(&typeof_scope, &typeof_scope.base, .{ .rl = .none }, args[0], node);
...@@ -8551,6 +8552,8 @@ fn cImport(...@@ -8551,6 +8552,8 @@ fn cImport(
8551 const astgen = gz.astgen;8552 const astgen = gz.astgen;
8552 const gpa = astgen.gpa;8553 const gpa = astgen.gpa;
85538554
8555 if (gz.c_import) return gz.astgen.failNode(node, "cannot nest @cImport", .{});
8556
8554 var block_scope = gz.makeSubBlock(scope);8557 var block_scope = gz.makeSubBlock(scope);
8555 block_scope.force_comptime = true;8558 block_scope.force_comptime = true;
8556 block_scope.c_import = true;8559 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,
...@@ -13468,7 +13478,6 @@ fn zirOverflowArithmetic(...@@ -13468,7 +13478,6 @@ fn zirOverflowArithmetic(
13468 const maybe_rhs_val = try sema.resolveMaybeUndefVal(rhs);13478 const maybe_rhs_val = try sema.resolveMaybeUndefVal(rhs);
1346913479
13470 const tuple_ty = try sema.overflowArithmeticTupleType(dest_ty);13480 const tuple_ty = try sema.overflowArithmeticTupleType(dest_ty);
13471 const ov_ty = tuple_ty.tupleFields().types[1];
13472 // TODO: Remove and use `ov_ty` instead.13481 // TODO: Remove and use `ov_ty` instead.
13473 // This is a temporary type used until overflow arithmetic properly returns `u1` instead of `bool`.13482 // This is a temporary type used until overflow arithmetic properly returns `u1` instead of `bool`.
13474 const overflowed_ty = if (dest_ty.zigTypeTag() == .Vector) try Type.vector(sema.arena, dest_ty.vectorLen(), Type.@"bool") else Type.@"bool";13483 const overflowed_ty = if (dest_ty.zigTypeTag() == .Vector) try Type.vector(sema.arena, dest_ty.vectorLen(), Type.@"bool") else Type.@"bool";
...@@ -13619,14 +13628,7 @@ fn zirOverflowArithmetic(...@@ -13619,14 +13628,7 @@ fn zirOverflowArithmetic(
13619 try sema.storePtr2(block, src, ptr, ptr_src, wrapped, src, .store);13628 try sema.storePtr2(block, src, ptr, ptr_src, wrapped, src, .store);
1362013629
13621 const overflow_bit = try sema.tupleFieldValByIndex(block, src, tuple, 1, tuple_ty);13630 const overflow_bit = try sema.tupleFieldValByIndex(block, src, tuple, 1, tuple_ty);
13622 const zero_ov_val = if (dest_ty.zigTypeTag() == .Vector) try Value.Tag.repeated.create(sema.arena, Value.zero) else Value.zero;13631 return block.addBitCast(overflowed_ty, overflow_bit);
13623 const zero_ov = try sema.addConstant(ov_ty, zero_ov_val);
13624
13625 const overflowed_inst = if (dest_ty.zigTypeTag() == .Vector)
13626 block.addCmpVector(overflow_bit, .zero, .neq, try sema.addType(ov_ty))
13627 else
13628 block.addBinOp(.cmp_neq, overflow_bit, zero_ov);
13629 return overflowed_inst;
13630 };13632 };
1363113633
13632 try sema.storePtr2(block, src, ptr, ptr_src, result.wrapped, src, .store);13634 try sema.storePtr2(block, src, ptr, ptr_src, result.wrapped, src, .store);
...@@ -22714,7 +22716,8 @@ fn fieldPtr(...@@ -22714,7 +22716,8 @@ fn fieldPtr(
22714 return inst;22716 return inst;
22715 }22717 }
22716 }22718 }
22717 if (child_type.unionTagType()) |enum_ty| {22719 const union_ty = try sema.resolveTypeFields(child_type);
22720 if (union_ty.unionTagType()) |enum_ty| {
22718 if (enum_ty.enumFieldIndex(field_name)) |field_index| {22721 if (enum_ty.enumFieldIndex(field_name)) |field_index| {
22719 const field_index_u32 = @intCast(u32, field_index);22722 const field_index_u32 = @intCast(u32, field_index);
22720 var anon_decl = try block.startAnonDecl();22723 var anon_decl = try block.startAnonDecl();
...@@ -29122,20 +29125,7 @@ fn resolveStructLayout(sema: *Sema, ty: Type) CompileError!void {...@@ -29122,20 +29125,7 @@ fn resolveStructLayout(sema: *Sema, ty: Type) CompileError!void {
29122 }29125 }
2912329126
29124 struct_obj.status = .have_layout;29127 struct_obj.status = .have_layout;
2912529128 _ = try sema.resolveTypeRequiresComptime(resolved_ty);
29126 // In case of querying the ABI alignment of this struct, we will ask
29127 // for hasRuntimeBits() of each field, so we need "requires comptime"
29128 // to be known already before this function returns.
29129 for (struct_obj.fields.values()) |field, i| {
29130 _ = sema.typeRequiresComptime(field.ty) catch |err| switch (err) {
29131 error.AnalysisFail => {
29132 const msg = sema.err orelse return err;
29133 try sema.addFieldErrNote(ty, i, msg, "while checking this field", .{});
29134 return err;
29135 },
29136 else => return err,
29137 };
29138 }
29139 }29129 }
29140 // otherwise it's a tuple; no need to resolve anything29130 // otherwise it's a tuple; no need to resolve anything
29141}29131}
...@@ -29299,6 +29289,198 @@ fn resolveUnionLayout(sema: *Sema, ty: Type) CompileError!void {...@@ -29299,6 +29289,198 @@ fn resolveUnionLayout(sema: *Sema, ty: Type) CompileError!void {
29299 };29289 };
29300 }29290 }
29301 union_obj.status = .have_layout;29291 union_obj.status = .have_layout;
29292 _ = try sema.resolveTypeRequiresComptime(resolved_ty);
29293}
29294
29295// In case of querying the ABI alignment of this struct, we will ask
29296// for hasRuntimeBits() of each field, so we need "requires comptime"
29297// to be known already before this function returns.
29298pub fn resolveTypeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {
29299 return switch (ty.tag()) {
29300 .u1,
29301 .u8,
29302 .i8,
29303 .u16,
29304 .i16,
29305 .u29,
29306 .u32,
29307 .i32,
29308 .u64,
29309 .i64,
29310 .u128,
29311 .i128,
29312 .usize,
29313 .isize,
29314 .c_short,
29315 .c_ushort,
29316 .c_int,
29317 .c_uint,
29318 .c_long,
29319 .c_ulong,
29320 .c_longlong,
29321 .c_ulonglong,
29322 .c_longdouble,
29323 .f16,
29324 .f32,
29325 .f64,
29326 .f80,
29327 .f128,
29328 .anyopaque,
29329 .bool,
29330 .void,
29331 .anyerror,
29332 .noreturn,
29333 .@"anyframe",
29334 .null,
29335 .undefined,
29336 .atomic_order,
29337 .atomic_rmw_op,
29338 .calling_convention,
29339 .address_space,
29340 .float_mode,
29341 .reduce_op,
29342 .call_options,
29343 .prefetch_options,
29344 .export_options,
29345 .extern_options,
29346 .manyptr_u8,
29347 .manyptr_const_u8,
29348 .manyptr_const_u8_sentinel_0,
29349 .const_slice_u8,
29350 .const_slice_u8_sentinel_0,
29351 .anyerror_void_error_union,
29352 .empty_struct_literal,
29353 .empty_struct,
29354 .error_set,
29355 .error_set_single,
29356 .error_set_inferred,
29357 .error_set_merged,
29358 .@"opaque",
29359 .generic_poison,
29360 .array_u8,
29361 .array_u8_sentinel_0,
29362 .int_signed,
29363 .int_unsigned,
29364 .enum_simple,
29365 => false,
29366
29367 .single_const_pointer_to_comptime_int,
29368 .type,
29369 .comptime_int,
29370 .comptime_float,
29371 .enum_literal,
29372 .type_info,
29373 // These are function bodies, not function pointers.
29374 .fn_noreturn_no_args,
29375 .fn_void_no_args,
29376 .fn_naked_noreturn_no_args,
29377 .fn_ccc_void_no_args,
29378 .function,
29379 => true,
29380
29381 .var_args_param => unreachable,
29382 .inferred_alloc_mut => unreachable,
29383 .inferred_alloc_const => unreachable,
29384 .bound_fn => unreachable,
29385
29386 .array,
29387 .array_sentinel,
29388 .vector,
29389 => return sema.resolveTypeRequiresComptime(ty.childType()),
29390
29391 .pointer,
29392 .single_const_pointer,
29393 .single_mut_pointer,
29394 .many_const_pointer,
29395 .many_mut_pointer,
29396 .c_const_pointer,
29397 .c_mut_pointer,
29398 .const_slice,
29399 .mut_slice,
29400 => {
29401 const child_ty = ty.childType();
29402 if (child_ty.zigTypeTag() == .Fn) {
29403 return child_ty.fnInfo().is_generic;
29404 } else {
29405 return sema.resolveTypeRequiresComptime(child_ty);
29406 }
29407 },
29408
29409 .optional,
29410 .optional_single_mut_pointer,
29411 .optional_single_const_pointer,
29412 => {
29413 var buf: Type.Payload.ElemType = undefined;
29414 return sema.resolveTypeRequiresComptime(ty.optionalChild(&buf));
29415 },
29416
29417 .tuple, .anon_struct => {
29418 const tuple = ty.tupleFields();
29419 for (tuple.types) |field_ty, i| {
29420 const have_comptime_val = tuple.values[i].tag() != .unreachable_value;
29421 if (!have_comptime_val and try sema.resolveTypeRequiresComptime(field_ty)) {
29422 return true;
29423 }
29424 }
29425 return false;
29426 },
29427
29428 .@"struct" => {
29429 const struct_obj = ty.castTag(.@"struct").?.data;
29430 switch (struct_obj.requires_comptime) {
29431 .no, .wip => return false,
29432 .yes => return true,
29433 .unknown => {
29434 var requires_comptime = false;
29435 struct_obj.requires_comptime = .wip;
29436 for (struct_obj.fields.values()) |field| {
29437 if (try sema.resolveTypeRequiresComptime(field.ty)) requires_comptime = true;
29438 }
29439 if (requires_comptime) {
29440 struct_obj.requires_comptime = .yes;
29441 } else {
29442 struct_obj.requires_comptime = .no;
29443 }
29444 return requires_comptime;
29445 },
29446 }
29447 },
29448
29449 .@"union", .union_safety_tagged, .union_tagged => {
29450 const union_obj = ty.cast(Type.Payload.Union).?.data;
29451 switch (union_obj.requires_comptime) {
29452 .no, .wip => return false,
29453 .yes => return true,
29454 .unknown => {
29455 var requires_comptime = false;
29456 union_obj.requires_comptime = .wip;
29457 for (union_obj.fields.values()) |field| {
29458 if (try sema.resolveTypeRequiresComptime(field.ty)) requires_comptime = true;
29459 }
29460 if (requires_comptime) {
29461 union_obj.requires_comptime = .yes;
29462 } else {
29463 union_obj.requires_comptime = .no;
29464 }
29465 return requires_comptime;
29466 },
29467 }
29468 },
29469
29470 .error_union => return sema.resolveTypeRequiresComptime(ty.errorUnionPayload()),
29471 .anyframe_T => {
29472 const child_ty = ty.castTag(.anyframe_T).?.data;
29473 return sema.resolveTypeRequiresComptime(child_ty);
29474 },
29475 .enum_numbered => {
29476 const tag_ty = ty.castTag(.enum_numbered).?.data.tag_ty;
29477 return sema.resolveTypeRequiresComptime(tag_ty);
29478 },
29479 .enum_full, .enum_nonexhaustive => {
29480 const tag_ty = ty.cast(Type.Payload.EnumFull).?.data.tag_ty;
29481 return sema.resolveTypeRequiresComptime(tag_ty);
29482 },
29483 };
29302}29484}
2930329485
29304/// Returns `error.AnalysisFail` if any of the types (recursively) failed to29486/// 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