diff --git a/src/Sema.zig b/src/Sema.zig index fc743c3ba9..9597447865 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -2771,20 +2771,16 @@ fn zirStr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins // expression of a variable declaration. We need the memory to be in the new // anonymous Decl's arena. - var new_decl_arena = std.heap.ArenaAllocator.init(sema.gpa); - errdefer new_decl_arena.deinit(); + var anon_decl = try block.startAnonDecl(); + defer anon_decl.deinit(); - const bytes = try new_decl_arena.allocator.dupeZ(u8, zir_bytes); + const bytes = try anon_decl.arena().dupeZ(u8, zir_bytes); - const decl_ty = try Type.Tag.array_u8_sentinel_0.create(&new_decl_arena.allocator, bytes.len); - const decl_val = try Value.Tag.bytes.create(&new_decl_arena.allocator, bytes[0 .. bytes.len + 1]); + const new_decl = try anon_decl.finish( + try Type.Tag.array_u8_sentinel_0.create(anon_decl.arena(), bytes.len), + try Value.Tag.bytes.create(anon_decl.arena(), bytes[0 .. bytes.len + 1]), + ); - const new_decl = try sema.mod.createAnonymousDecl(block, .{ - .ty = decl_ty, - .val = decl_val, - }); - errdefer sema.mod.abortAnonDecl(new_decl); - try new_decl.finalizeNewArena(&new_decl_arena); return sema.analyzeDeclRef(new_decl); } @@ -9741,8 +9737,20 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I fn zirTypeName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].un_node; - const src = inst_data.src(); - return sema.fail(block, src, "TODO: Sema.zirTypeName", .{}); + const ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; + const ty = try sema.resolveType(block, ty_src, inst_data.operand); + + var anon_decl = try block.startAnonDecl(); + defer anon_decl.deinit(); + + const bytes = try ty.nameAlloc(anon_decl.arena()); + + const new_decl = try anon_decl.finish( + try Type.Tag.array_u8_sentinel_0.create(anon_decl.arena(), bytes.len), + try Value.Tag.bytes.create(anon_decl.arena(), bytes[0 .. bytes.len + 1]), + ); + + return sema.analyzeDeclRef(new_decl); } fn zirFrameType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { diff --git a/src/stage1/codegen.cpp b/src/stage1/codegen.cpp index 163813194b..131c3a1082 100644 --- a/src/stage1/codegen.cpp +++ b/src/stage1/codegen.cpp @@ -8755,17 +8755,17 @@ static void define_builtin_types(CodeGen *g) { } { ZigType *entry = new_type_table_entry(ZigTypeIdEnumLiteral); - buf_init_from_str(&entry->name, "(enum literal)"); + buf_init_from_str(&entry->name, "@Type(.EnumLiteral)"); g->builtin_types.entry_enum_literal = entry; } { ZigType *entry = new_type_table_entry(ZigTypeIdUndefined); - buf_init_from_str(&entry->name, "(undefined)"); + buf_init_from_str(&entry->name, "@Type(.Undefined)"); g->builtin_types.entry_undef = entry; } { ZigType *entry = new_type_table_entry(ZigTypeIdNull); - buf_init_from_str(&entry->name, "(null)"); + buf_init_from_str(&entry->name, "@Type(.Null)"); g->builtin_types.entry_null = entry; } { diff --git a/src/type.zig b/src/type.zig index 9bd4e42b0d..bea07781e7 100644 --- a/src/type.zig +++ b/src/type.zig @@ -1197,6 +1197,113 @@ pub const Type = extern union { } } + /// Returns a name suitable for `@typeName`. + pub fn nameAlloc(ty: Type, arena: *Allocator) Allocator.Error![:0]const u8 { + const t = ty.tag(); + switch (t) { + .inferred_alloc_const => unreachable, + .inferred_alloc_mut => unreachable, + .generic_poison => unreachable, + + .u1, + .u8, + .i8, + .u16, + .i16, + .u32, + .i32, + .u64, + .i64, + .u128, + .i128, + .usize, + .isize, + .c_short, + .c_ushort, + .c_int, + .c_uint, + .c_long, + .c_ulong, + .c_longlong, + .c_ulonglong, + .c_longdouble, + .c_void, + .f16, + .f32, + .f64, + .f128, + .bool, + .void, + .type, + .anyerror, + .@"anyframe", + .comptime_int, + .comptime_float, + .noreturn, + .var_args_param, + .bound_fn, + => return @tagName(t), + + .enum_literal => return "@Type(.EnumLiteral)", + .@"null" => return "@Type(.Null)", + .@"undefined" => return "@Type(.Undefined)", + + .empty_struct, .empty_struct_literal => return "struct {}", + + .@"struct" => { + const struct_obj = ty.castTag(.@"struct").?.data; + return try arena.dupeZ(u8, std.mem.sliceTo(struct_obj.owner_decl.name, 0)); + }, + .@"union", .union_tagged => { + const union_obj = ty.cast(Payload.Union).?.data; + return try arena.dupeZ(u8, std.mem.sliceTo(union_obj.owner_decl.name, 0)); + }, + .enum_full, .enum_nonexhaustive => { + const enum_full = ty.cast(Payload.EnumFull).?.data; + return try arena.dupeZ(u8, std.mem.sliceTo(enum_full.owner_decl.name, 0)); + }, + .enum_simple => { + const enum_simple = ty.castTag(.enum_simple).?.data; + return try arena.dupeZ(u8, std.mem.sliceTo(enum_simple.owner_decl.name, 0)); + }, + .enum_numbered => { + const enum_numbered = ty.castTag(.enum_numbered).?.data; + return try arena.dupeZ(u8, std.mem.sliceTo(enum_numbered.owner_decl.name, 0)); + }, + .@"opaque" => { + // TODO use declaration name + return "opaque {}"; + }, + + .anyerror_void_error_union => return "anyerror!void", + .const_slice_u8 => return "[]const u8", + .fn_noreturn_no_args => return "fn() noreturn", + .fn_void_no_args => return "fn() void", + .fn_naked_noreturn_no_args => return "fn() callconv(.Naked) noreturn", + .fn_ccc_void_no_args => return "fn() callconv(.C) void", + .single_const_pointer_to_comptime_int => return "*const comptime_int", + .manyptr_u8 => return "[*]u8", + .manyptr_const_u8 => return "[*]const u8", + .atomic_order => return "AtomicOrder", + .atomic_rmw_op => return "AtomicRmwOp", + .calling_convention => return "CallingConvention", + .address_space => return "AddressSpace", + .float_mode => return "FloatMode", + .reduce_op => return "ReduceOp", + .call_options => return "CallOptions", + .export_options => return "ExportOptions", + .extern_options => return "ExternOptions", + .type_info => return "TypeInfo", + + else => { + // TODO this is wasteful and also an incorrect implementation of `@typeName` + var buf = std.ArrayList(u8).init(arena); + try buf.writer().print("{}", .{ty}); + return try buf.toOwnedSliceSentinel(0); + }, + } + } + /// Anything that reports hasCodeGenBits() false returns false here as well. /// `generic_poison` will return false. pub fn requiresComptime(ty: Type) bool { diff --git a/test/behavior.zig b/test/behavior.zig index 2da66e841b..b251c418e7 100644 --- a/test/behavior.zig +++ b/test/behavior.zig @@ -24,11 +24,11 @@ test { _ = @import("behavior/defer.zig"); _ = @import("behavior/enum.zig"); _ = @import("behavior/error.zig"); - _ = @import("behavior/error.zig"); _ = @import("behavior/generics.zig"); _ = @import("behavior/hasdecl.zig"); _ = @import("behavior/hasfield.zig"); _ = @import("behavior/if.zig"); + _ = @import("behavior/import.zig"); _ = @import("behavior/int128.zig"); _ = @import("behavior/member_func.zig"); _ = @import("behavior/null.zig"); @@ -73,7 +73,9 @@ test { _ = @import("behavior/slice.zig"); _ = @import("behavior/struct_llvm.zig"); _ = @import("behavior/switch.zig"); + _ = @import("behavior/undefined.zig"); _ = @import("behavior/union.zig"); + _ = @import("behavior/void.zig"); _ = @import("behavior/widening.zig"); if (builtin.zig_is_stage2) { @@ -151,7 +153,6 @@ test { _ = @import("behavior/fn_in_struct_in_comptime.zig"); _ = @import("behavior/for_stage1.zig"); _ = @import("behavior/if_stage1.zig"); - _ = @import("behavior/import.zig"); _ = @import("behavior/incomplete_struct_param_tld.zig"); _ = @import("behavior/inttoptr.zig"); _ = @import("behavior/ir_block_deps.zig"); @@ -183,13 +184,11 @@ test { _ = @import("behavior/type.zig"); _ = @import("behavior/type_info.zig"); _ = @import("behavior/typename.zig"); - _ = @import("behavior/undefined.zig"); _ = @import("behavior/union_stage1.zig"); _ = @import("behavior/union_with_members.zig"); _ = @import("behavior/usingnamespace_stage1.zig"); _ = @import("behavior/var_args.zig"); _ = @import("behavior/vector.zig"); - _ = @import("behavior/void.zig"); if (builtin.target.cpu.arch == .wasm32) { _ = @import("behavior/wasm.zig"); } diff --git a/test/behavior/enum.zig b/test/behavior/enum.zig index 684115b992..5a3777a1d7 100644 --- a/test/behavior/enum.zig +++ b/test/behavior/enum.zig @@ -583,3 +583,25 @@ test "peer type resolution with enum literal" { try expect(Items.two == .two); try expect(.two == Items.two); } + +const MultipleChoice = enum(u32) { + A = 20, + B = 40, + C = 60, + D = 1000, +}; + +fn testEnumWithSpecifiedTagValues(x: MultipleChoice) !void { + try expect(@enumToInt(x) == 60); + try expect(1234 == switch (x) { + MultipleChoice.A => 1, + MultipleChoice.B => 2, + MultipleChoice.C => @as(u32, 1234), + MultipleChoice.D => 4, + }); +} + +test "enum with specified tag values" { + try testEnumWithSpecifiedTagValues(MultipleChoice.C); + comptime try testEnumWithSpecifiedTagValues(MultipleChoice.C); +} diff --git a/test/behavior/enum_stage1.zig b/test/behavior/enum_stage1.zig index 57f5eed6a2..747aa5ed34 100644 --- a/test/behavior/enum_stage1.zig +++ b/test/behavior/enum_stage1.zig @@ -2,28 +2,6 @@ const expect = @import("std").testing.expect; const mem = @import("std").mem; const Tag = @import("std").meta.Tag; -const MultipleChoice = enum(u32) { - A = 20, - B = 40, - C = 60, - D = 1000, -}; - -fn testEnumWithSpecifiedTagValues(x: MultipleChoice) !void { - try expect(@enumToInt(x) == 60); - try expect(1234 == switch (x) { - MultipleChoice.A => 1, - MultipleChoice.B => 2, - MultipleChoice.C => @as(u32, 1234), - MultipleChoice.D => 4, - }); -} - -test "enum with specified tag values" { - try testEnumWithSpecifiedTagValues(MultipleChoice.C); - comptime try testEnumWithSpecifiedTagValues(MultipleChoice.C); -} - test "non-exhaustive enum" { const S = struct { const E = enum(u8) { diff --git a/test/behavior/fn.zig b/test/behavior/fn.zig index db1059a427..3a1f3e0b35 100644 --- a/test/behavior/fn.zig +++ b/test/behavior/fn.zig @@ -163,3 +163,84 @@ fn fComplexCallconvRet(x: u32) callconv(blk: { test "function with complex callconv and return type expressions" { try expect(fComplexCallconvRet(3).x == 9); } + +test "pass by non-copying value" { + try expect(addPointCoords(Point{ .x = 1, .y = 2 }) == 3); +} + +const Point = struct { + x: i32, + y: i32, +}; + +fn addPointCoords(pt: Point) i32 { + return pt.x + pt.y; +} + +test "pass by non-copying value through var arg" { + try expect((try addPointCoordsVar(Point{ .x = 1, .y = 2 })) == 3); +} + +fn addPointCoordsVar(pt: anytype) !i32 { + comptime try expect(@TypeOf(pt) == Point); + return pt.x + pt.y; +} + +test "pass by non-copying value as method" { + var pt = Point2{ .x = 1, .y = 2 }; + try expect(pt.addPointCoords() == 3); +} + +const Point2 = struct { + x: i32, + y: i32, + + fn addPointCoords(self: Point2) i32 { + return self.x + self.y; + } +}; + +test "pass by non-copying value as method, which is generic" { + var pt = Point3{ .x = 1, .y = 2 }; + try expect(pt.addPointCoords(i32) == 3); +} + +const Point3 = struct { + x: i32, + y: i32, + + fn addPointCoords(self: Point3, comptime T: type) i32 { + _ = T; + return self.x + self.y; + } +}; + +test "pass by non-copying value as method, at comptime" { + comptime { + var pt = Point2{ .x = 1, .y = 2 }; + try expect(pt.addPointCoords() == 3); + } +} + +test "implicit cast fn call result to optional in field result" { + const S = struct { + fn entry() !void { + var x = Foo{ + .field = optionalPtr(), + }; + try expect(x.field.?.* == 999); + } + + const glob: i32 = 999; + + fn optionalPtr() *const i32 { + return &glob; + } + + const Foo = struct { + field: ?*const i32, + }; + }; + try S.entry(); + comptime try S.entry(); +} diff --git a/test/behavior/fn_stage1.zig b/test/behavior/fn_stage1.zig index 66eb40296e..18663f2e10 100644 --- a/test/behavior/fn_stage1.zig +++ b/test/behavior/fn_stage1.zig @@ -56,87 +56,6 @@ fn numberLiteralArg(a: anytype) !void { try expect(a == 3); } -test "pass by non-copying value" { - try expect(addPointCoords(Point{ .x = 1, .y = 2 }) == 3); -} - -const Point = struct { - x: i32, - y: i32, -}; - -fn addPointCoords(pt: Point) i32 { - return pt.x + pt.y; -} - -test "pass by non-copying value through var arg" { - try expect((try addPointCoordsVar(Point{ .x = 1, .y = 2 })) == 3); -} - -fn addPointCoordsVar(pt: anytype) !i32 { - comptime try expect(@TypeOf(pt) == Point); - return pt.x + pt.y; -} - -test "pass by non-copying value as method" { - var pt = Point2{ .x = 1, .y = 2 }; - try expect(pt.addPointCoords() == 3); -} - -const Point2 = struct { - x: i32, - y: i32, - - fn addPointCoords(self: Point2) i32 { - return self.x + self.y; - } -}; - -test "pass by non-copying value as method, which is generic" { - var pt = Point3{ .x = 1, .y = 2 }; - try expect(pt.addPointCoords(i32) == 3); -} - -const Point3 = struct { - x: i32, - y: i32, - - fn addPointCoords(self: Point3, comptime T: type) i32 { - _ = T; - return self.x + self.y; - } -}; - -test "pass by non-copying value as method, at comptime" { - comptime { - var pt = Point2{ .x = 1, .y = 2 }; - try expect(pt.addPointCoords() == 3); - } -} - -test "implicit cast fn call result to optional in field result" { - const S = struct { - fn entry() !void { - var x = Foo{ - .field = optionalPtr(), - }; - try expect(x.field.?.* == 999); - } - - const glob: i32 = 999; - - fn optionalPtr() *const i32 { - return &glob; - } - - const Foo = struct { - field: ?*const i32, - }; - }; - try S.entry(); - comptime try S.entry(); -} - test "function call with anon list literal" { const S = struct { fn doTheTest() !void { diff --git a/test/behavior/for.zig b/test/behavior/for.zig index 47babe7125..d16f1d44cd 100644 --- a/test/behavior/for.zig +++ b/test/behavior/for.zig @@ -60,3 +60,59 @@ test "ignore lval with underscore (for loop)" { break; } } + +test "basic for loop" { + const expected_result = [_]u8{ 9, 8, 7, 6, 0, 1, 2, 3 } ** 3; + + var buffer: [expected_result.len]u8 = undefined; + var buf_index: usize = 0; + + const array = [_]u8{ 9, 8, 7, 6 }; + for (array) |item| { + buffer[buf_index] = item; + buf_index += 1; + } + for (array) |item, index| { + _ = item; + buffer[buf_index] = @intCast(u8, index); + buf_index += 1; + } + const array_ptr = &array; + for (array_ptr) |item| { + buffer[buf_index] = item; + buf_index += 1; + } + for (array_ptr) |item, index| { + _ = item; + buffer[buf_index] = @intCast(u8, index); + buf_index += 1; + } + const unknown_size: []const u8 = &array; + for (unknown_size) |item| { + buffer[buf_index] = item; + buf_index += 1; + } + for (unknown_size) |_, index| { + buffer[buf_index] = @intCast(u8, index); + buf_index += 1; + } + + try expect(mem.eql(u8, buffer[0..buf_index], &expected_result)); +} + +test "for with null and T peer types and inferred result location type" { + const S = struct { + fn doTheTest(slice: []const u8) !void { + if (for (slice) |item| { + if (item == 10) { + break item; + } + } else null) |v| { + _ = v; + @panic("fail"); + } + } + }; + try S.doTheTest(&[_]u8{ 1, 2 }); + comptime try S.doTheTest(&[_]u8{ 1, 2 }); +} diff --git a/test/behavior/for_stage1.zig b/test/behavior/for_stage1.zig index 898be21d2a..b9fe7b68ea 100644 --- a/test/behavior/for_stage1.zig +++ b/test/behavior/for_stage1.zig @@ -26,45 +26,6 @@ fn mangleString(s: []u8) void { } } -test "basic for loop" { - const expected_result = [_]u8{ 9, 8, 7, 6, 0, 1, 2, 3 } ** 3; - - var buffer: [expected_result.len]u8 = undefined; - var buf_index: usize = 0; - - const array = [_]u8{ 9, 8, 7, 6 }; - for (array) |item| { - buffer[buf_index] = item; - buf_index += 1; - } - for (array) |item, index| { - _ = item; - buffer[buf_index] = @intCast(u8, index); - buf_index += 1; - } - const array_ptr = &array; - for (array_ptr) |item| { - buffer[buf_index] = item; - buf_index += 1; - } - for (array_ptr) |item, index| { - _ = item; - buffer[buf_index] = @intCast(u8, index); - buf_index += 1; - } - const unknown_size: []const u8 = &array; - for (unknown_size) |item| { - buffer[buf_index] = item; - buf_index += 1; - } - for (unknown_size) |_, index| { - buffer[buf_index] = @intCast(u8, index); - buf_index += 1; - } - - try expect(mem.eql(u8, buffer[0..buf_index], &expected_result)); -} - test "2 break statements and an else" { const S = struct { fn entry(t: bool, f: bool) !void { @@ -82,23 +43,6 @@ test "2 break statements and an else" { comptime try S.entry(true, false); } -test "for with null and T peer types and inferred result location type" { - const S = struct { - fn doTheTest(slice: []const u8) !void { - if (for (slice) |item| { - if (item == 10) { - break item; - } - } else null) |v| { - _ = v; - @panic("fail"); - } - } - }; - try S.doTheTest(&[_]u8{ 1, 2 }); - comptime try S.doTheTest(&[_]u8{ 1, 2 }); -} - test "for copies its payload" { const S = struct { fn doTheTest() !void { diff --git a/test/behavior/import.zig b/test/behavior/import.zig index 2018ee0b93..e6c3d81111 100644 --- a/test/behavior/import.zig +++ b/test/behavior/import.zig @@ -3,7 +3,7 @@ const expectEqual = @import("std").testing.expectEqual; const a_namespace = @import("import/a_namespace.zig"); test "call fn via namespace lookup" { - try expectEqual(@as(i32, 1234), a_namespace.foo()); + try expect(@as(i32, 1234) == a_namespace.foo()); } test "importing the same thing gives the same import" { @@ -14,7 +14,7 @@ test "import in non-toplevel scope" { const S = struct { usingnamespace @import("import/a_namespace.zig"); }; - try expectEqual(@as(i32, 1234), S.foo()); + try expect(@as(i32, 1234) == S.foo()); } test "import empty file" { diff --git a/test/behavior/null.zig b/test/behavior/null.zig index e4c4f26bb8..861921d39c 100644 --- a/test/behavior/null.zig +++ b/test/behavior/null.zig @@ -115,3 +115,28 @@ test "optional pointer to 0 bit type null value at runtime" { var x: ?*EmptyStruct = null; try expect(x == null); } + +test "if var maybe pointer" { + try expect(shouldBeAPlus1(Particle{ + .a = 14, + .b = 1, + .c = 1, + .d = 1, + }) == 15); +} +fn shouldBeAPlus1(p: Particle) u64 { + var maybe_particle: ?Particle = p; + if (maybe_particle) |*particle| { + particle.a += 1; + } + if (maybe_particle) |particle| { + return particle.a; + } + return 0; +} +const Particle = struct { + a: u64, + b: u64, + c: u64, + d: u64, +}; diff --git a/test/behavior/undefined.zig b/test/behavior/undefined.zig index a160f86221..69fba3633d 100644 --- a/test/behavior/undefined.zig +++ b/test/behavior/undefined.zig @@ -65,5 +65,5 @@ test "assign undefined to struct with method" { test "type name of undefined" { const x = undefined; - try expect(mem.eql(u8, @typeName(@TypeOf(x)), "(undefined)")); + try expect(mem.eql(u8, @typeName(@TypeOf(x)), "@Type(.Undefined)")); } diff --git a/test/behavior/while.zig b/test/behavior/while.zig index 9e9ac5dc01..f2f0bc0bbe 100644 --- a/test/behavior/while.zig +++ b/test/behavior/while.zig @@ -153,6 +153,20 @@ test "while with optional as condition with else" { try expect(got_else == 1); } +test "while with error union condition" { + numbers_left = 10; + var sum: i32 = 0; + var got_else: i32 = 0; + while (getNumberOrErr()) |value| { + sum += value; + } else |err| { + try expect(err == error.OutOfNumbers); + got_else += 1; + } + try expect(sum == 45); + try expect(got_else == 1); +} + test "while on bool with else result follow else prong" { const result = while (returnFalse()) { break @as(i32, 10); @@ -199,3 +213,26 @@ fn returnFalse() bool { fn returnTrue() bool { return true; } + +test "return with implicit cast from while loop" { + returnWithImplicitCastFromWhileLoopTest() catch unreachable; +} +fn returnWithImplicitCastFromWhileLoopTest() anyerror!void { + while (true) { + return; + } +} + +test "while on error union with else result follow else prong" { + const result = while (returnError()) |value| { + break value; + } else |_| @as(i32, 2); + try expect(result == 2); +} + +test "while on error union with else result follow break prong" { + const result = while (returnSuccess(10)) |value| { + break value; + } else |_| @as(i32, 2); + try expect(result == 10); +} diff --git a/test/behavior/while_stage1.zig b/test/behavior/while_stage1.zig index 2ab19d66e1..4eac3d9aa7 100644 --- a/test/behavior/while_stage1.zig +++ b/test/behavior/while_stage1.zig @@ -1,76 +1,6 @@ const std = @import("std"); const expect = std.testing.expect; -test "return with implicit cast from while loop" { - returnWithImplicitCastFromWhileLoopTest() catch unreachable; -} -fn returnWithImplicitCastFromWhileLoopTest() anyerror!void { - while (true) { - return; - } -} - -test "while with error union condition" { - numbers_left = 10; - var sum: i32 = 0; - var got_else: i32 = 0; - while (getNumberOrErr()) |value| { - sum += value; - } else |err| { - try expect(err == error.OutOfNumbers); - got_else += 1; - } - try expect(sum == 45); - try expect(got_else == 1); -} - -var numbers_left: i32 = undefined; -fn getNumberOrErr() anyerror!i32 { - return if (numbers_left == 0) error.OutOfNumbers else x: { - numbers_left -= 1; - break :x numbers_left; - }; -} -fn getNumberOrNull() ?i32 { - return if (numbers_left == 0) null else x: { - numbers_left -= 1; - break :x numbers_left; - }; -} - -test "while on error union with else result follow else prong" { - const result = while (returnError()) |value| { - break value; - } else |_| @as(i32, 2); - try expect(result == 2); -} - -test "while on error union with else result follow break prong" { - const result = while (returnSuccess(10)) |value| { - break value; - } else |_| @as(i32, 2); - try expect(result == 10); -} - -fn returnNull() ?i32 { - return null; -} -fn returnOptional(x: i32) ?i32 { - return x; -} -fn returnError() anyerror!i32 { - return error.YouWantedAnError; -} -fn returnSuccess(x: i32) anyerror!i32 { - return x; -} -fn returnFalse() bool { - return false; -} -fn returnTrue() bool { - return true; -} - test "while bool 2 break statements and an else" { const S = struct { fn entry(t: bool, f: bool) !void { diff --git a/test/compile_errors.zig b/test/compile_errors.zig index d717125fb2..91b81c20e5 100644 --- a/test/compile_errors.zig +++ b/test/compile_errors.zig @@ -2674,7 +2674,7 @@ pub fn addCases(ctx: *TestContext) !void { \\ } \\} , &[_][]const u8{ - "tmp.zig:3:9: error: expected type 'error{Hi}', found '(enum literal)'", + "tmp.zig:3:9: error: expected type 'error{Hi}', found '@Type(.EnumLiteral)'", }); ctx.objErrStage1("@sizeOf bad type", @@ -2682,7 +2682,7 @@ pub fn addCases(ctx: *TestContext) !void { \\ return @sizeOf(@TypeOf(null)); \\} , &[_][]const u8{ - "tmp.zig:2:20: error: no size available for type '(null)'", + "tmp.zig:2:20: error: no size available for type '@Type(.Null)'", }); ctx.objErrStage1("generic function where return type is self-referenced", @@ -5783,7 +5783,7 @@ pub fn addCases(ctx: *TestContext) !void { \\ \\export fn entry() usize { return @sizeOf(@TypeOf(a)); } , &[_][]const u8{ - "tmp.zig:1:16: error: expected type '*u8', found '(null)'", + "tmp.zig:1:16: error: expected type '*u8', found '@Type(.Null)'", }); ctx.objErrStage1("indexing an array of size zero", @@ -7506,12 +7506,12 @@ pub fn addCases(ctx: *TestContext) !void { \\}; , &[_][]const u8{ "tmp.zig:2:4: error: variable of type '*const comptime_int' must be const or comptime", - "tmp.zig:6:4: error: variable of type '(undefined)' must be const or comptime", + "tmp.zig:6:4: error: variable of type '@Type(.Undefined)' must be const or comptime", "tmp.zig:10:4: error: variable of type 'comptime_int' must be const or comptime", "tmp.zig:10:4: note: to modify this variable at runtime, it must be given an explicit fixed-size number type", "tmp.zig:14:4: error: variable of type 'comptime_float' must be const or comptime", "tmp.zig:14:4: note: to modify this variable at runtime, it must be given an explicit fixed-size number type", - "tmp.zig:18:4: error: variable of type '(null)' must be const or comptime", + "tmp.zig:18:4: error: variable of type '@Type(.Null)' must be const or comptime", "tmp.zig:22:4: error: variable of type 'Opaque' not allowed", "tmp.zig:26:4: error: variable of type 'type' must be const or comptime", "tmp.zig:30:4: error: variable of type '(bound fn(*const Foo) void)' must be const or comptime", @@ -8278,8 +8278,8 @@ pub fn addCases(ctx: *TestContext) !void { , &[_][]const u8{ "tmp.zig:2:18: error: Opaque return type 'FooType' not allowed", "tmp.zig:1:1: note: type declared here", - "tmp.zig:5:18: error: Null return type '(null)' not allowed", - "tmp.zig:8:18: error: Undefined return type '(undefined)' not allowed", + "tmp.zig:5:18: error: Null return type '@Type(.Null)' not allowed", + "tmp.zig:8:18: error: Undefined return type '@Type(.Undefined)' not allowed", }); ctx.objErrStage1("generic function returning opaque type", @@ -8300,9 +8300,9 @@ pub fn addCases(ctx: *TestContext) !void { "tmp.zig:6:16: error: call to generic function with Opaque return type 'FooType' not allowed", "tmp.zig:2:1: note: function declared here", "tmp.zig:1:1: note: type declared here", - "tmp.zig:9:16: error: call to generic function with Null return type '(null)' not allowed", + "tmp.zig:9:16: error: call to generic function with Null return type '@Type(.Null)' not allowed", "tmp.zig:2:1: note: function declared here", - "tmp.zig:12:16: error: call to generic function with Undefined return type '(undefined)' not allowed", + "tmp.zig:12:16: error: call to generic function with Undefined return type '@Type(.Undefined)' not allowed", "tmp.zig:2:1: note: function declared here", }); @@ -8329,9 +8329,9 @@ pub fn addCases(ctx: *TestContext) !void { \\} , &[_][]const u8{ "tmp.zig:3:28: error: parameter of opaque type 'FooType' not allowed", - "tmp.zig:8:28: error: parameter of type '(null)' not allowed", + "tmp.zig:8:28: error: parameter of type '@Type(.Null)' not allowed", "tmp.zig:12:11: error: parameter of opaque type 'FooType' not allowed", - "tmp.zig:17:11: error: parameter of type '(null)' not allowed", + "tmp.zig:17:11: error: parameter of type '@Type(.Null)' not allowed", }); ctx.objErrStage1( // fixed bug #2032