Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: ziglang/zig
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: bd13e757e7e3
Choose a base ref
...
head repository: ziglang/zig
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: d3693dca73df
Choose a head ref
  • 2 commits
  • 6 files changed
  • 1 contributor

Commits on Jun 6, 2018

  1. Copy the full SHA
    76c8efd View commit details
  2. Pointer Reform: update @typeinfo

     * add assertion for trying to do @typeinfo on global error set
     * remove TypeInfo.Slice
     * add TypeInfo.Pointer.Size with possible values
       - One
       - Many
       - Slice
    
    See #770
    andrewrk committed Jun 6, 2018
    Copy the full SHA
    d3693dc View commit details
Showing with 111 additions and 55 deletions.
  1. +1 −1 src/analyze.cpp
  2. +7 −4 src/codegen.cpp
  3. +50 −30 src/ir.cpp
  4. +19 −12 std/fmt/index.zig
  5. +25 −8 test/cases/type_info.zig
  6. +9 −0 test/compile_errors.zig
2 changes: 1 addition & 1 deletion src/analyze.cpp
Original file line number Diff line number Diff line change
@@ -5981,7 +5981,7 @@ size_t type_id_index(TypeTableEntry *entry) {
return 7;
case TypeTableEntryIdStruct:
if (entry->data.structure.is_slice)
return 25;
return 6;
return 8;
case TypeTableEntryIdComptimeFloat:
return 9;
11 changes: 7 additions & 4 deletions src/codegen.cpp
Original file line number Diff line number Diff line change
@@ -6481,7 +6481,6 @@ static void define_builtin_compile_vars(CodeGen *g) {
const TypeTableEntryId id = type_id_at_index(i);
buf_appendf(contents, " %s,\n", type_id_name(id));
}
buf_appendf(contents, " Slice,\n");
buf_appendf(contents, "};\n\n");
}
{
@@ -6494,7 +6493,6 @@ static void define_builtin_compile_vars(CodeGen *g) {
" Int: Int,\n"
" Float: Float,\n"
" Pointer: Pointer,\n"
" Slice: Slice,\n"
" Array: Array,\n"
" Struct: Struct,\n"
" ComptimeFloat: void,\n"
@@ -6524,13 +6522,18 @@ static void define_builtin_compile_vars(CodeGen *g) {
" };\n"
"\n"
" pub const Pointer = struct {\n"
" size: Size,\n"
" is_const: bool,\n"
" is_volatile: bool,\n"
" alignment: u32,\n"
" child: type,\n"
" };\n"
"\n"
" pub const Slice = Pointer;\n"
" pub const Size = enum {\n"
" One,\n"
" Many,\n"
" Slice,\n"
" };\n"
" };\n"
"\n"
" pub const Array = struct {\n"
" len: usize,\n"
80 changes: 50 additions & 30 deletions src/ir.cpp
Original file line number Diff line number Diff line change
@@ -16222,8 +16222,7 @@ static bool ir_make_type_info_defs(IrAnalyze *ira, ConstExprValue *out_val, Scop
return true;
}

static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, TypeTableEntry *type_entry)
{
static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, TypeTableEntry *type_entry) {
assert(type_entry != nullptr);
assert(!type_is_invalid(type_entry));

@@ -16248,38 +16247,67 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, TypeTableEntry *t
enum_field_val->data.x_struct.fields = inner_fields;
};

const auto create_ptr_like_type_info = [ira](const char *name, TypeTableEntry *ptr_type_entry) {
const auto create_ptr_like_type_info = [ira](TypeTableEntry *ptr_type_entry) {
TypeTableEntry *attrs_type;
uint32_t size_enum_index;
if (is_slice(ptr_type_entry)) {
attrs_type = ptr_type_entry->data.structure.fields[slice_ptr_index].type_entry;
size_enum_index = 2;
} else if (ptr_type_entry->id == TypeTableEntryIdPointer) {
attrs_type = ptr_type_entry;
size_enum_index = (ptr_type_entry->data.pointer.ptr_len == PtrLenSingle) ? 0 : 1;
} else {
zig_unreachable();
}

TypeTableEntry *type_info_pointer_type = ir_type_info_get_type(ira, "Pointer");
ensure_complete_type(ira->codegen, type_info_pointer_type);
assert(!type_is_invalid(type_info_pointer_type));

ConstExprValue *result = create_const_vals(1);
result->special = ConstValSpecialStatic;
result->type = ir_type_info_get_type(ira, name);
result->type = type_info_pointer_type;

ConstExprValue *fields = create_const_vals(4);
ConstExprValue *fields = create_const_vals(5);
result->data.x_struct.fields = fields;

// is_const: bool
ensure_field_index(result->type, "is_const", 0);
// size: Size
ensure_field_index(result->type, "size", 0);
TypeTableEntry *type_info_pointer_size_type = ir_type_info_get_type(ira, "Size", type_info_pointer_type);
ensure_complete_type(ira->codegen, type_info_pointer_size_type);
assert(!type_is_invalid(type_info_pointer_size_type));
fields[0].special = ConstValSpecialStatic;
fields[0].type = ira->codegen->builtin_types.entry_bool;
fields[0].data.x_bool = ptr_type_entry->data.pointer.is_const;
// is_volatile: bool
ensure_field_index(result->type, "is_volatile", 1);
fields[0].type = type_info_pointer_size_type;
bigint_init_unsigned(&fields[0].data.x_enum_tag, size_enum_index);

// is_const: bool
ensure_field_index(result->type, "is_const", 1);
fields[1].special = ConstValSpecialStatic;
fields[1].type = ira->codegen->builtin_types.entry_bool;
fields[1].data.x_bool = ptr_type_entry->data.pointer.is_volatile;
// alignment: u32
ensure_field_index(result->type, "alignment", 2);
fields[1].data.x_bool = attrs_type->data.pointer.is_const;
// is_volatile: bool
ensure_field_index(result->type, "is_volatile", 2);
fields[2].special = ConstValSpecialStatic;
fields[2].type = ira->codegen->builtin_types.entry_u32;
bigint_init_unsigned(&fields[2].data.x_bigint, ptr_type_entry->data.pointer.alignment);
// child: type
ensure_field_index(result->type, "child", 3);
fields[2].type = ira->codegen->builtin_types.entry_bool;
fields[2].data.x_bool = attrs_type->data.pointer.is_volatile;
// alignment: u32
ensure_field_index(result->type, "alignment", 3);
fields[3].special = ConstValSpecialStatic;
fields[3].type = ira->codegen->builtin_types.entry_type;
fields[3].data.x_type = ptr_type_entry->data.pointer.child_type;
fields[3].type = ira->codegen->builtin_types.entry_u32;
bigint_init_unsigned(&fields[3].data.x_bigint, attrs_type->data.pointer.alignment);
// child: type
ensure_field_index(result->type, "child", 4);
fields[4].special = ConstValSpecialStatic;
fields[4].type = ira->codegen->builtin_types.entry_type;
fields[4].data.x_type = attrs_type->data.pointer.child_type;

return result;
};

if (type_entry == ira->codegen->builtin_types.entry_global_error_set) {
zig_panic("TODO implement @typeInfo for global error set");
}

ConstExprValue *result = nullptr;
switch (type_entry->id)
{
@@ -16348,7 +16376,7 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, TypeTableEntry *t
}
case TypeTableEntryIdPointer:
{
result = create_ptr_like_type_info("Pointer", type_entry);
result = create_ptr_like_type_info(type_entry);
break;
}
case TypeTableEntryIdArray:
@@ -16621,15 +16649,7 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, TypeTableEntry *t
case TypeTableEntryIdStruct:
{
if (type_entry->data.structure.is_slice) {
Buf ptr_field_name = BUF_INIT;
buf_init_from_str(&ptr_field_name, "ptr");
TypeTableEntry *ptr_type = type_entry->data.structure.fields_by_name.get(&ptr_field_name)->type_entry;
ensure_complete_type(ira->codegen, ptr_type);
if (type_is_invalid(ptr_type))
return nullptr;
buf_deinit(&ptr_field_name);

result = create_ptr_like_type_info("Slice", ptr_type);
result = create_ptr_like_type_info(type_entry);
break;
}

31 changes: 19 additions & 12 deletions std/fmt/index.zig
Original file line number Diff line number Diff line change
@@ -97,7 +97,11 @@ pub fn formatType(
output: fn (@typeOf(context), []const u8) Errors!void,
) Errors!void {
const T = @typeOf(value);
switch (@typeId(T)) {
if (T == error) {
try output(context, "error.");
return output(context, @errorName(value));
}
switch (@typeInfo(T)) {
builtin.TypeId.Int, builtin.TypeId.Float => {
return formatValue(value, fmt, context, Errors, output);
},
@@ -125,12 +129,13 @@ pub fn formatType(
try output(context, "error.");
return output(context, @errorName(value));
},
builtin.TypeId.Pointer => {
switch (@typeId(T.Child)) {
builtin.TypeId.Array => {
if (T.Child.Child == u8) {
builtin.TypeId.Pointer => |ptr_info| switch (ptr_info.size) {
builtin.TypeInfo.Pointer.Size.One => switch (@typeInfo(ptr_info.child)) {
builtin.TypeId.Array => |info| {
if (info.child == u8) {
return formatText(value, fmt, context, Errors, output);
}
return format(context, Errors, output, "{}@{x}", @typeName(T.Child), @ptrToInt(value));
},
builtin.TypeId.Enum, builtin.TypeId.Union, builtin.TypeId.Struct => {
const has_cust_fmt = comptime cf: {
@@ -154,14 +159,16 @@ pub fn formatType(
return format(context, Errors, output, "{}@{x}", @typeName(T.Child), @ptrToInt(value));
},
else => return format(context, Errors, output, "{}@{x}", @typeName(T.Child), @ptrToInt(value)),
}
},
else => if (@canImplicitCast([]const u8, value)) {
const casted_value = ([]const u8)(value);
return output(context, casted_value);
} else {
@compileError("Unable to format type '" ++ @typeName(T) ++ "'");
},
builtin.TypeInfo.Pointer.Size.Many => {
return format(context, Errors, output, "{}@{x}", @typeName(T.Child), @ptrToInt(value));
},
builtin.TypeInfo.Pointer.Size.Slice => {
const casted_value = ([]const u8)(value);
return output(context, casted_value);
},
},
else => @compileError("Unable to format type '" ++ @typeName(T) ++ "'"),
}
}

33 changes: 25 additions & 8 deletions test/cases/type_info.zig
Original file line number Diff line number Diff line change
@@ -39,24 +39,41 @@ test "type info: pointer type info" {
fn testPointer() void {
const u32_ptr_info = @typeInfo(*u32);
assert(TypeId(u32_ptr_info) == TypeId.Pointer);
assert(u32_ptr_info.Pointer.size == TypeInfo.Pointer.Size.One);
assert(u32_ptr_info.Pointer.is_const == false);
assert(u32_ptr_info.Pointer.is_volatile == false);
assert(u32_ptr_info.Pointer.alignment == 4);
assert(u32_ptr_info.Pointer.alignment == @alignOf(u32));
assert(u32_ptr_info.Pointer.child == u32);
}

test "type info: unknown length pointer type info" {
testUnknownLenPtr();
comptime testUnknownLenPtr();
}

fn testUnknownLenPtr() void {
const u32_ptr_info = @typeInfo([*]const volatile f64);
assert(TypeId(u32_ptr_info) == TypeId.Pointer);
assert(u32_ptr_info.Pointer.size == TypeInfo.Pointer.Size.Many);
assert(u32_ptr_info.Pointer.is_const == true);
assert(u32_ptr_info.Pointer.is_volatile == true);
assert(u32_ptr_info.Pointer.alignment == @alignOf(f64));
assert(u32_ptr_info.Pointer.child == f64);
}

test "type info: slice type info" {
testSlice();
comptime testSlice();
}

fn testSlice() void {
const u32_slice_info = @typeInfo([]u32);
assert(TypeId(u32_slice_info) == TypeId.Slice);
assert(u32_slice_info.Slice.is_const == false);
assert(u32_slice_info.Slice.is_volatile == false);
assert(u32_slice_info.Slice.alignment == 4);
assert(u32_slice_info.Slice.child == u32);
assert(TypeId(u32_slice_info) == TypeId.Pointer);
assert(u32_slice_info.Pointer.size == TypeInfo.Pointer.Size.Slice);
assert(u32_slice_info.Pointer.is_const == false);
assert(u32_slice_info.Pointer.is_volatile == false);
assert(u32_slice_info.Pointer.alignment == 4);
assert(u32_slice_info.Pointer.child == u32);
}

test "type info: array type info" {
@@ -149,11 +166,11 @@ fn testUnion() void {
assert(TypeId(typeinfo_info) == TypeId.Union);
assert(typeinfo_info.Union.layout == TypeInfo.ContainerLayout.Auto);
assert(typeinfo_info.Union.tag_type == TypeId);
assert(typeinfo_info.Union.fields.len == 26);
assert(typeinfo_info.Union.fields.len == 25);
assert(typeinfo_info.Union.fields[4].enum_field != null);
assert((??typeinfo_info.Union.fields[4].enum_field).value == 4);
assert(typeinfo_info.Union.fields[4].field_type == @typeOf(@typeInfo(u8).Int));
assert(typeinfo_info.Union.defs.len == 21);
assert(typeinfo_info.Union.defs.len == 20);

const TestNoTagUnion = union {
Foo: void,
9 changes: 9 additions & 0 deletions test/compile_errors.zig
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
const tests = @import("tests.zig");

pub fn addCases(cases: *tests.CompileErrorContext) void {
cases.add(
"attempted implicit cast from T to [*]const T",
\\export fn entry() void {
\\ const x: [*]const bool = true;
\\}
,
".tmp_source.zig:2:30: error: expected type '[*]const bool', found 'bool'",
);

cases.add(
"dereference unknown length pointer",
\\export fn entry(x: [*]i32) i32 {