Need Help Understanding the fields of Zig std.builtin.Type

I run into a lot of Zig code that uses @typeInfo and this returns std.builtin.Type

I checked the documentation here Zig Documentation and would appreciate some clarification regarding some of the fields.

For Pointer field

  • It has a Size field, that can either be One, Many, Slice and C so I am guessing this many, single item pointer, many item pointer, if it is a slice, C pointer. If so, the follow up question is, are there other properties on Pointer that have special meaning depending on what Size it is?
  • what does is_const and is_volatile mean?
  • it has a child: type field. What does this mean?
  • What does is_allowzero mean?
  • What about sentinel? I was assuming this is meant to be the sentinel value that ends what is being pointed too…but I might be wrong

For ErrorSet

  • What is the error_set in ErrorSet?
  • And then what is the payload?

Trying to investigate, I try this:

    const error_set = error{One, Two};
    std.debug.print("{any}", .{@typeInfo(@TypeOf(error_set))});

zig run src/main.zig
builtin.Type{ .Type = void }%

And the output I got is not what I was expecting. I thought it would be the ErrorSet variant, but it is Type which brings me to the next question.

For Type

  • How come in std.builtin.Type there is also a Type variant? I mean is that not cyclical? But no, because the .Type is just void.

For NoReturn

  • Not sure what kind of Type this refers to

For AnyFrame:

  • Similar to NoReturn, not sure what kind of Type this refers to.

For Struct

  • Basically not sure I understand any of the fields: layout, backing_integer, fields, decls, is_tuple. Fields I can guess to be the fields, while decls are the methods? But not sure about the rest.

Explanation of the above or a pointer to where I can read up on them would be appreciated.

  • is_const means that the contents–that the pointer points to–are read only.
    e.g. *const u8 is a pointer to a single read only byte.
  • is_volatile means that the contents are volatile i.e. can change by hardware (memory mapped I/O)
    e.g. *volatile u32 is a pointer to a 32 bit unsigned integer that is hardware controlled (it is not memory).

Is the type that the pointer points to. (e.g. for *u8 the child type is u8)

If it is true, it means that 0 is a valid address.

Yes, it is the sentinel value. (e.g. [*:0]u8 many u8 that end with 0)

It is a slice of errors. For each error in the error set there is the name of the error.
e.g. error{InvalidNumber,Unknown}


Your error set is already a type.

    const Error_set = error{One, Two};
    std.debug.print("{any}", .{@typeInfo(Error_set)});

Some times @compileLog(x) is useful to see the type and value of x when compiling.
e.g.

const error_set = error{One, Two};
@compileLog(error_set);

displays:

error: found compile log statement
    @compileLog(error_set);
    ^~~~~~~~~~~~~~~~~~~~~~

Compile Log Output:
@as(type, error{One,Two})

  • NoReturn is about functions marked as noreturn e.g. std.process.exit
  • backing_integer the integer that implements a packed struct.
  • is_tuple a structure without named fields is a tuple.
  • fields the fields of the structure.
  • decls the declarations (functions, const and var) in the structure.

see also:

12 Likes