Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

special forms of struct and union which allow setting properties via comptime values #8643

Open
andrewrk opened this issue Apr 29, 2021 · 5 comments
Labels
accepted This proposal is planned. proposal This issue suggests modifications. If it also has the "accepted" label then it is planned.
Milestone

Comments

@andrewrk
Copy link
Member

andrewrk commented Apr 29, 2021

Add this to std.builtin:

pub const UnionProperties = struct {
    layout: ContainerLayout = .Auto,
    tag: union(enum) {
        none,
        auto,
        int: type,
        type: type,
    } = .none,
};
pub const StructProperties = struct {
    layout: ContainerLayout = .Auto,
};

New builtins and syntax

@struct(comptime props: StructProperties)
@union(comptime props: UnionProperties)

Use these in place of struct and union keywords respectively.

Existing struct and union syntax is unchanged. This is not a breaking proposal.

Example usage

const S = @struct(.{ .layout = .Extern }) {
   field1: i32,
   field2: f64,

   pub fn foo() void {}
};
const data_props: std.builtin.UnionProperties = if (safety_on) .{
   .layout = .Auto,
   .tag = .auto,
} else .{
   .layout = .Extern,
   .tag = .none,
};
const Data = @union(data_props) {
  one: i32,
  two: i32,
  pub fn decl() void {}
};

Motivation and real use case

The use case is having both safety in a safe build, and well-defined memory layout in release mode, for fast serialization/deserialization. We have exactly this use case in self-hosted compiler, for the Zir.Inst.Data union. I would imagine pretty much every video game will have this same use case.

It is also planned to experiment with adding safety to structs as well, so the same use case applies there as well.

Considerations with other open proposals

@andrewrk andrewrk added proposal This issue suggests modifications. If it also has the "accepted" label then it is planned. accepted This proposal is planned. labels Apr 29, 2021
@andrewrk andrewrk added this to the 0.9.0 milestone Apr 29, 2021
@ghost
Copy link

ghost commented Apr 29, 2021

So now the grammar of the language needs special cases for these builtins. Hmm.

@SpexGuy
Copy link
Contributor

SpexGuy commented Apr 29, 2021

Builtins are already a special case in the parser. The spec grammar will need to have some modifications made, but that would have been the case for any solution to this problem.

@LemonBoy
Copy link
Contributor

From the syntax PoV I prefer what's proposed in #4245 where the optional UnionProperties/StructProperties go between struct/union and the opening brace. My reasoning is that:

  1. I don't like builtins
  2. @struct and @union become a second way of defining a container type
  3. There's a precedent in extern "foo"

The only possible downside I see is that a user may specify a conflicting set of parameters (eg. extern struct (.{.layout = .Packed})), but that's easily caught by the compiler so... not a big deal?

Revised example usage

const S = struct (.{ .layout = .Extern }) {
   field1: i32,
   field2: f64,

   pub fn foo() void {}
};

@daurnimator
Copy link
Contributor

daurnimator commented May 1, 2021

Especially once we have #1717 I'm not sure why we should prefer this over enhancing @Type:

const S = @Type(.{
    .Struct = .{
        .layout = .Extern,
        .fields = &[_]StructField{
            .{ .name = "field1", .field_type = i32 },
            .{ .name = "field2", .field_type = f64 },
        },
        .decls = &[_]Declaration{
            .{ .name = "foo", .is_pub = true, .data = .{ .Fn = fn () void{} } },
        },
        .is_tuple = false,
    },
});

With some default values in std.builtin types and/or some helper functions, this could become more ergonomic.

@andrewrk andrewrk modified the milestones: 0.9.0, 0.10.0 May 19, 2021
@Inve1951
Copy link
Contributor

This might run into #4630 or become a workaround for it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
accepted This proposal is planned. proposal This issue suggests modifications. If it also has the "accepted" label then it is planned.
Projects
None yet
Development

No branches or pull requests

5 participants