Commit dfbc063f79

Andrew Kelley <andrew@ziglang.org>
2019-02-03 22:13:28
`std.mem.Allocator.create` replaced with better API
`std.mem.Allocator.createOne` is renamed to `std.mem.Allocator.create`. The problem with the previous API is that even after copy elision, the initalization value passed as a parameter would always be a copy. With the new API, once copy elision is done, initialization functions can directly initialize allocated memory in place. Related: * #1872 * #1873
1 parent c90c256
src-self-hosted/compilation.zig
@@ -83,10 +83,11 @@ pub const ZigCompiler = struct {
         const context_ref = c.LLVMContextCreate() orelse return error.OutOfMemory;
         errdefer c.LLVMContextDispose(context_ref);
 
-        const node = try self.loop.allocator.create(std.atomic.Stack(llvm.ContextRef).Node{
+        const node = try self.loop.allocator.create(std.atomic.Stack(llvm.ContextRef).Node);
+        node.* = std.atomic.Stack(llvm.ContextRef).Node{
             .next = undefined,
             .data = context_ref,
-        });
+        };
         errdefer self.loop.allocator.destroy(node);
 
         return LlvmHandle{ .node = node };
@@ -596,7 +597,8 @@ pub const Compilation = struct {
     }
 
     fn initTypes(comp: *Compilation) !void {
-        comp.meta_type = try comp.arena().create(Type.MetaType{
+        comp.meta_type = try comp.arena().create(Type.MetaType);
+        comp.meta_type.* = Type.MetaType{
             .base = Type{
                 .name = "type",
                 .base = Value{
@@ -608,12 +610,13 @@ pub const Compilation = struct {
                 .abi_alignment = Type.AbiAlignment.init(comp.loop),
             },
             .value = undefined,
-        });
+        };
         comp.meta_type.value = &comp.meta_type.base;
         comp.meta_type.base.base.typ = &comp.meta_type.base;
         assert((try comp.primitive_type_table.put(comp.meta_type.base.name, &comp.meta_type.base)) == null);
 
-        comp.void_type = try comp.arena().create(Type.Void{
+        comp.void_type = try comp.arena().create(Type.Void);
+        comp.void_type.* = Type.Void{
             .base = Type{
                 .name = "void",
                 .base = Value{
@@ -624,10 +627,11 @@ pub const Compilation = struct {
                 .id = builtin.TypeId.Void,
                 .abi_alignment = Type.AbiAlignment.init(comp.loop),
             },
-        });
+        };
         assert((try comp.primitive_type_table.put(comp.void_type.base.name, &comp.void_type.base)) == null);
 
-        comp.noreturn_type = try comp.arena().create(Type.NoReturn{
+        comp.noreturn_type = try comp.arena().create(Type.NoReturn);
+        comp.noreturn_type.* = Type.NoReturn{
             .base = Type{
                 .name = "noreturn",
                 .base = Value{
@@ -638,10 +642,11 @@ pub const Compilation = struct {
                 .id = builtin.TypeId.NoReturn,
                 .abi_alignment = Type.AbiAlignment.init(comp.loop),
             },
-        });
+        };
         assert((try comp.primitive_type_table.put(comp.noreturn_type.base.name, &comp.noreturn_type.base)) == null);
 
-        comp.comptime_int_type = try comp.arena().create(Type.ComptimeInt{
+        comp.comptime_int_type = try comp.arena().create(Type.ComptimeInt);
+        comp.comptime_int_type.* = Type.ComptimeInt{
             .base = Type{
                 .name = "comptime_int",
                 .base = Value{
@@ -652,10 +657,11 @@ pub const Compilation = struct {
                 .id = builtin.TypeId.ComptimeInt,
                 .abi_alignment = Type.AbiAlignment.init(comp.loop),
             },
-        });
+        };
         assert((try comp.primitive_type_table.put(comp.comptime_int_type.base.name, &comp.comptime_int_type.base)) == null);
 
-        comp.bool_type = try comp.arena().create(Type.Bool{
+        comp.bool_type = try comp.arena().create(Type.Bool);
+        comp.bool_type.* = Type.Bool{
             .base = Type{
                 .name = "bool",
                 .base = Value{
@@ -666,45 +672,50 @@ pub const Compilation = struct {
                 .id = builtin.TypeId.Bool,
                 .abi_alignment = Type.AbiAlignment.init(comp.loop),
             },
-        });
+        };
         assert((try comp.primitive_type_table.put(comp.bool_type.base.name, &comp.bool_type.base)) == null);
 
-        comp.void_value = try comp.arena().create(Value.Void{
+        comp.void_value = try comp.arena().create(Value.Void);
+        comp.void_value.* = Value.Void{
             .base = Value{
                 .id = Value.Id.Void,
                 .typ = &Type.Void.get(comp).base,
                 .ref_count = std.atomic.Int(usize).init(1),
             },
-        });
+        };
 
-        comp.true_value = try comp.arena().create(Value.Bool{
+        comp.true_value = try comp.arena().create(Value.Bool);
+        comp.true_value.* = Value.Bool{
             .base = Value{
                 .id = Value.Id.Bool,
                 .typ = &Type.Bool.get(comp).base,
                 .ref_count = std.atomic.Int(usize).init(1),
             },
             .x = true,
-        });
+        };
 
-        comp.false_value = try comp.arena().create(Value.Bool{
+        comp.false_value = try comp.arena().create(Value.Bool);
+        comp.false_value.* = Value.Bool{
             .base = Value{
                 .id = Value.Id.Bool,
                 .typ = &Type.Bool.get(comp).base,
                 .ref_count = std.atomic.Int(usize).init(1),
             },
             .x = false,
-        });
+        };
 
-        comp.noreturn_value = try comp.arena().create(Value.NoReturn{
+        comp.noreturn_value = try comp.arena().create(Value.NoReturn);
+        comp.noreturn_value.* = Value.NoReturn{
             .base = Value{
                 .id = Value.Id.NoReturn,
                 .typ = &Type.NoReturn.get(comp).base,
                 .ref_count = std.atomic.Int(usize).init(1),
             },
-        });
+        };
 
         for (CInt.list) |cint, i| {
-            const c_int_type = try comp.arena().create(Type.Int{
+            const c_int_type = try comp.arena().create(Type.Int);
+            c_int_type.* = Type.Int{
                 .base = Type{
                     .name = cint.zig_name,
                     .base = Value{
@@ -720,11 +731,12 @@ pub const Compilation = struct {
                     .bit_count = comp.target.cIntTypeSizeInBits(cint.id),
                 },
                 .garbage_node = undefined,
-            });
+            };
             comp.c_int_types[i] = c_int_type;
             assert((try comp.primitive_type_table.put(cint.zig_name, &c_int_type.base)) == null);
         }
-        comp.u8_type = try comp.arena().create(Type.Int{
+        comp.u8_type = try comp.arena().create(Type.Int);
+        comp.u8_type.* = Type.Int{
             .base = Type{
                 .name = "u8",
                 .base = Value{
@@ -740,7 +752,7 @@ pub const Compilation = struct {
                 .bit_count = 8,
             },
             .garbage_node = undefined,
-        });
+        };
         assert((try comp.primitive_type_table.put(comp.u8_type.base.name, &comp.u8_type.base)) == null);
     }
 
@@ -829,7 +841,7 @@ pub const Compilation = struct {
             };
             errdefer self.gpa().free(source_code);
 
-            const tree = try self.gpa().createOne(ast.Tree);
+            const tree = try self.gpa().create(ast.Tree);
             tree.* = try std.zig.parse(self.gpa(), source_code);
             errdefer {
                 tree.deinit();
@@ -925,7 +937,8 @@ pub const Compilation = struct {
                         }
                     } else {
                         // add new decl
-                        const fn_decl = try self.gpa().create(Decl.Fn{
+                        const fn_decl = try self.gpa().create(Decl.Fn);
+                        fn_decl.* = Decl.Fn{
                             .base = Decl{
                                 .id = Decl.Id.Fn,
                                 .name = name,
@@ -936,7 +949,7 @@ pub const Compilation = struct {
                             },
                             .value = Decl.Fn.Val{ .Unresolved = {} },
                             .fn_proto = fn_proto,
-                        });
+                        };
                         tree_scope.base.ref();
                         errdefer self.gpa().destroy(fn_decl);
 
@@ -1140,12 +1153,13 @@ pub const Compilation = struct {
             }
         }
 
-        const link_lib = try self.gpa().create(LinkLib{
+        const link_lib = try self.gpa().create(LinkLib);
+        link_lib.* = LinkLib{
             .name = name,
             .path = null,
             .provided_explicitly = provided_explicitly,
             .symbols = ArrayList([]u8).init(self.gpa()),
-        });
+        };
         try self.link_libs_list.append(link_lib);
         if (is_libc) {
             self.libc_link_lib = link_lib;
src-self-hosted/errmsg.zig
@@ -118,7 +118,8 @@ pub const Msg = struct {
         const realpath = try mem.dupe(comp.gpa(), u8, tree_scope.root().realpath);
         errdefer comp.gpa().free(realpath);
 
-        const msg = try comp.gpa().create(Msg{
+        const msg = try comp.gpa().create(Msg);
+        msg.* = Msg{
             .text = text,
             .realpath = realpath,
             .data = Data{
@@ -128,7 +129,7 @@ pub const Msg = struct {
                     .span = span,
                 },
             },
-        });
+        };
         tree_scope.base.ref();
         return msg;
     }
@@ -139,13 +140,14 @@ pub const Msg = struct {
         const realpath_copy = try mem.dupe(comp.gpa(), u8, realpath);
         errdefer comp.gpa().free(realpath_copy);
 
-        const msg = try comp.gpa().create(Msg{
+        const msg = try comp.gpa().create(Msg);
+        msg.* = Msg{
             .text = text,
             .realpath = realpath_copy,
             .data = Data{
                 .Cli = Cli{ .allocator = comp.gpa() },
             },
-        });
+        };
         return msg;
     }
 
@@ -164,7 +166,8 @@ pub const Msg = struct {
         var out_stream = &std.io.BufferOutStream.init(&text_buf).stream;
         try parse_error.render(&tree_scope.tree.tokens, out_stream);
 
-        const msg = try comp.gpa().create(Msg{
+        const msg = try comp.gpa().create(Msg);
+        msg.* = Msg{
             .text = undefined,
             .realpath = realpath_copy,
             .data = Data{
@@ -177,7 +180,7 @@ pub const Msg = struct {
                     },
                 },
             },
-        });
+        };
         tree_scope.base.ref();
         msg.text = text_buf.toOwnedSlice();
         return msg;
@@ -203,7 +206,8 @@ pub const Msg = struct {
         var out_stream = &std.io.BufferOutStream.init(&text_buf).stream;
         try parse_error.render(&tree.tokens, out_stream);
 
-        const msg = try allocator.create(Msg{
+        const msg = try allocator.create(Msg);
+        msg.* = Msg{
             .text = undefined,
             .realpath = realpath_copy,
             .data = Data{
@@ -216,7 +220,7 @@ pub const Msg = struct {
                     },
                 },
             },
-        });
+        };
         msg.text = text_buf.toOwnedSlice();
         errdefer allocator.destroy(msg);
 
src-self-hosted/ir.zig
@@ -1021,12 +1021,13 @@ pub const Builder = struct {
     pub const Error = Analyze.Error;
 
     pub fn init(comp: *Compilation, tree_scope: *Scope.AstTree, begin_scope: ?*Scope) !Builder {
-        const code = try comp.gpa().create(Code{
+        const code = try comp.gpa().create(Code);
+        code.* = Code{
             .basic_block_list = undefined,
             .arena = std.heap.ArenaAllocator.init(comp.gpa()),
             .return_type = null,
             .tree_scope = tree_scope,
-        });
+        };
         code.basic_block_list = std.ArrayList(*BasicBlock).init(&code.arena.allocator);
         errdefer code.destroy(comp.gpa());
 
@@ -1052,7 +1053,8 @@ pub const Builder = struct {
 
     /// No need to clean up resources thanks to the arena allocator.
     pub fn createBasicBlock(self: *Builder, scope: *Scope, name_hint: [*]const u8) !*BasicBlock {
-        const basic_block = try self.arena().create(BasicBlock{
+        const basic_block = try self.arena().create(BasicBlock);
+        basic_block.* = BasicBlock{
             .ref_count = 0,
             .name_hint = name_hint,
             .debug_id = self.next_debug_id,
@@ -1063,7 +1065,7 @@ pub const Builder = struct {
             .ref_instruction = null,
             .llvm_block = undefined,
             .llvm_exit_block = undefined,
-        });
+        };
         self.next_debug_id += 1;
         return basic_block;
     }
@@ -1774,7 +1776,8 @@ pub const Builder = struct {
         params: I.Params,
         is_generated: bool,
     ) !*Inst {
-        const inst = try self.arena().create(I{
+        const inst = try self.arena().create(I);
+        inst.* = I{
             .base = Inst{
                 .id = Inst.typeToId(I),
                 .is_generated = is_generated,
@@ -1793,7 +1796,7 @@ pub const Builder = struct {
                 .owner_bb = self.current_basic_block,
             },
             .params = params,
-        });
+        };
 
         // Look at the params and ref() other instructions
         comptime var i = 0;
src-self-hosted/main.zig
@@ -944,12 +944,13 @@ const CliPkg = struct {
     parent: ?*CliPkg,
 
     pub fn init(allocator: *mem.Allocator, name: []const u8, path: []const u8, parent: ?*CliPkg) !*CliPkg {
-        var pkg = try allocator.create(CliPkg{
+        var pkg = try allocator.create(CliPkg);
+        pkg.* = CliPkg{
             .name = name,
             .path = path,
             .children = ArrayList(*CliPkg).init(allocator),
             .parent = parent,
-        });
+        };
         return pkg;
     }
 
src-self-hosted/package.zig
@@ -15,11 +15,13 @@ pub const Package = struct {
     /// makes internal copies of root_src_dir and root_src_path
     /// allocator should be an arena allocator because Package never frees anything
     pub fn create(allocator: *mem.Allocator, root_src_dir: []const u8, root_src_path: []const u8) !*Package {
-        return allocator.create(Package{
+        const ptr = try allocator.create(Package);
+        ptr.* = Package{
             .root_src_dir = try Buffer.init(allocator, root_src_dir),
             .root_src_path = try Buffer.init(allocator, root_src_path),
             .table = Table.init(allocator),
-        });
+        };
+        return ptr;
     }
 
     pub fn add(self: *Package, name: []const u8, package: *Package) !void {
src-self-hosted/scope.zig
@@ -120,7 +120,7 @@ pub const Scope = struct {
         /// Creates a Root scope with 1 reference
         /// Takes ownership of realpath
         pub fn create(comp: *Compilation, realpath: []u8) !*Root {
-            const self = try comp.gpa().createOne(Root);
+            const self = try comp.gpa().create(Root);
             self.* = Root{
                 .base = Scope{
                     .id = Id.Root,
@@ -150,7 +150,7 @@ pub const Scope = struct {
         /// Creates a scope with 1 reference
         /// Takes ownership of tree, will deinit and destroy when done.
         pub fn create(comp: *Compilation, tree: *ast.Tree, root_scope: *Root) !*AstTree {
-            const self = try comp.gpa().createOne(AstTree);
+            const self = try comp.gpa().create(AstTree);
             self.* = AstTree{
                 .base = undefined,
                 .tree = tree,
@@ -182,7 +182,7 @@ pub const Scope = struct {
 
         /// Creates a Decls scope with 1 reference
         pub fn create(comp: *Compilation, parent: *Scope) !*Decls {
-            const self = try comp.gpa().createOne(Decls);
+            const self = try comp.gpa().create(Decls);
             self.* = Decls{
                 .base = undefined,
                 .table = event.RwLocked(Decl.Table).init(comp.loop, Decl.Table.init(comp.gpa())),
@@ -235,7 +235,7 @@ pub const Scope = struct {
 
         /// Creates a Block scope with 1 reference
         pub fn create(comp: *Compilation, parent: *Scope) !*Block {
-            const self = try comp.gpa().createOne(Block);
+            const self = try comp.gpa().create(Block);
             self.* = Block{
                 .base = undefined,
                 .incoming_values = undefined,
@@ -262,7 +262,7 @@ pub const Scope = struct {
         /// Creates a FnDef scope with 1 reference
         /// Must set the fn_val later
         pub fn create(comp: *Compilation, parent: *Scope) !*FnDef {
-            const self = try comp.gpa().createOne(FnDef);
+            const self = try comp.gpa().create(FnDef);
             self.* = FnDef{
                 .base = undefined,
                 .fn_val = null,
@@ -281,7 +281,7 @@ pub const Scope = struct {
 
         /// Creates a CompTime scope with 1 reference
         pub fn create(comp: *Compilation, parent: *Scope) !*CompTime {
-            const self = try comp.gpa().createOne(CompTime);
+            const self = try comp.gpa().create(CompTime);
             self.* = CompTime{ .base = undefined };
             self.base.init(Id.CompTime, parent);
             return self;
@@ -309,7 +309,7 @@ pub const Scope = struct {
             kind: Kind,
             defer_expr_scope: *DeferExpr,
         ) !*Defer {
-            const self = try comp.gpa().createOne(Defer);
+            const self = try comp.gpa().create(Defer);
             self.* = Defer{
                 .base = undefined,
                 .defer_expr_scope = defer_expr_scope,
@@ -333,7 +333,7 @@ pub const Scope = struct {
 
         /// Creates a DeferExpr scope with 1 reference
         pub fn create(comp: *Compilation, parent: *Scope, expr_node: *ast.Node) !*DeferExpr {
-            const self = try comp.gpa().createOne(DeferExpr);
+            const self = try comp.gpa().create(DeferExpr);
             self.* = DeferExpr{
                 .base = undefined,
                 .expr_node = expr_node,
@@ -398,7 +398,7 @@ pub const Scope = struct {
         }
 
         fn create(comp: *Compilation, parent: *Scope, name: []const u8, src_node: *ast.Node) !*Var {
-            const self = try comp.gpa().createOne(Var);
+            const self = try comp.gpa().create(Var);
             self.* = Var{
                 .base = undefined,
                 .name = name,
src-self-hosted/type.zig
@@ -413,7 +413,7 @@ pub const Type = struct {
             key.ref();
             errdefer key.deref(comp);
 
-            const self = try comp.gpa().createOne(Fn);
+            const self = try comp.gpa().create(Fn);
             self.* = Fn{
                 .base = undefined,
                 .key = key,
@@ -615,11 +615,12 @@ pub const Type = struct {
                 }
             }
 
-            const self = try comp.gpa().create(Int{
+            const self = try comp.gpa().create(Int);
+            self.* = Int{
                 .base = undefined,
                 .key = key,
                 .garbage_node = undefined,
-            });
+            };
             errdefer comp.gpa().destroy(self);
 
             const u_or_i = "ui"[@boolToInt(key.is_signed)];
@@ -781,11 +782,12 @@ pub const Type = struct {
                 }
             }
 
-            const self = try comp.gpa().create(Pointer{
+            const self = try comp.gpa().create(Pointer);
+            self.* = Pointer{
                 .base = undefined,
                 .key = normal_key,
                 .garbage_node = undefined,
-            });
+            };
             errdefer comp.gpa().destroy(self);
 
             const size_str = switch (self.key.size) {
@@ -879,11 +881,12 @@ pub const Type = struct {
                 }
             }
 
-            const self = try comp.gpa().create(Array{
+            const self = try comp.gpa().create(Array);
+            self.* = Array{
                 .base = undefined,
                 .key = key,
                 .garbage_node = undefined,
-            });
+            };
             errdefer comp.gpa().destroy(self);
 
             const name = try std.fmt.allocPrint(comp.gpa(), "[{}]{}", key.len, key.elem_type.name);
src-self-hosted/value.zig
@@ -135,14 +135,15 @@ pub const Value = struct {
         symbol_name: Buffer,
 
         pub fn create(comp: *Compilation, fn_type: *Type.Fn, symbol_name: Buffer) !*FnProto {
-            const self = try comp.gpa().create(FnProto{
+            const self = try comp.gpa().create(FnProto);
+            self.* = FnProto{
                 .base = Value{
                     .id = Value.Id.FnProto,
                     .typ = &fn_type.base,
                     .ref_count = std.atomic.Int(usize).init(1),
                 },
                 .symbol_name = symbol_name,
-            });
+            };
             fn_type.base.base.ref();
             return self;
         }
@@ -190,14 +191,16 @@ pub const Value = struct {
         /// Creates a Fn value with 1 ref
         /// Takes ownership of symbol_name
         pub fn create(comp: *Compilation, fn_type: *Type.Fn, fndef_scope: *Scope.FnDef, symbol_name: Buffer) !*Fn {
-            const link_set_node = try comp.gpa().create(Compilation.FnLinkSet.Node{
+            const link_set_node = try comp.gpa().create(Compilation.FnLinkSet.Node);
+            link_set_node.* = Compilation.FnLinkSet.Node{
                 .data = null,
                 .next = undefined,
                 .prev = undefined,
-            });
+            };
             errdefer comp.gpa().destroy(link_set_node);
 
-            const self = try comp.gpa().create(Fn{
+            const self = try comp.gpa().create(Fn);
+            self.* = Fn{
                 .base = Value{
                     .id = Value.Id.Fn,
                     .typ = &fn_type.base,
@@ -209,7 +212,7 @@ pub const Value = struct {
                 .symbol_name = symbol_name,
                 .containing_object = Buffer.initNull(comp.gpa()),
                 .link_set_node = link_set_node,
-            });
+            };
             fn_type.base.base.ref();
             fndef_scope.fn_val = self;
             fndef_scope.base.ref();
@@ -353,7 +356,8 @@ pub const Value = struct {
             var ptr_type_consumed = false;
             errdefer if (!ptr_type_consumed) ptr_type.base.base.deref(comp);
 
-            const self = try comp.gpa().create(Value.Ptr{
+            const self = try comp.gpa().create(Value.Ptr);
+            self.* = Value.Ptr{
                 .base = Value{
                     .id = Value.Id.Ptr,
                     .typ = &ptr_type.base,
@@ -366,7 +370,7 @@ pub const Value = struct {
                     },
                 },
                 .mut = Mut.CompTimeConst,
-            });
+            };
             ptr_type_consumed = true;
             errdefer comp.gpa().destroy(self);
 
@@ -430,14 +434,15 @@ pub const Value = struct {
             }) catch unreachable);
             errdefer array_type.base.base.deref(comp);
 
-            const self = try comp.gpa().create(Value.Array{
+            const self = try comp.gpa().create(Value.Array);
+            self.* = Value.Array{
                 .base = Value{
                     .id = Value.Id.Array,
                     .typ = &array_type.base,
                     .ref_count = std.atomic.Int(usize).init(1),
                 },
                 .special = Special{ .OwnedBuffer = buffer },
-            });
+            };
             errdefer comp.gpa().destroy(self);
 
             return self;
@@ -509,14 +514,15 @@ pub const Value = struct {
         big_int: std.math.big.Int,
 
         pub fn createFromString(comp: *Compilation, typ: *Type, base: u8, value: []const u8) !*Int {
-            const self = try comp.gpa().create(Value.Int{
+            const self = try comp.gpa().create(Value.Int);
+            self.* = Value.Int{
                 .base = Value{
                     .id = Value.Id.Int,
                     .typ = typ,
                     .ref_count = std.atomic.Int(usize).init(1),
                 },
                 .big_int = undefined,
-            });
+            };
             typ.base.ref();
             errdefer comp.gpa().destroy(self);
 
@@ -557,14 +563,15 @@ pub const Value = struct {
             old.base.typ.base.ref();
             errdefer old.base.typ.base.deref(comp);
 
-            const new = try comp.gpa().create(Value.Int{
+            const new = try comp.gpa().create(Value.Int);
+            new.* = Value.Int{
                 .base = Value{
                     .id = Value.Id.Int,
                     .typ = old.base.typ,
                     .ref_count = std.atomic.Int(usize).init(1),
                 },
                 .big_int = undefined,
-            });
+            };
             errdefer comp.gpa().destroy(new);
 
             new.big_int = try old.big_int.clone();
std/atomic/queue.zig
@@ -221,11 +221,12 @@ fn startPuts(ctx: *Context) u8 {
     while (put_count != 0) : (put_count -= 1) {
         std.os.time.sleep(1); // let the os scheduler be our fuzz
         const x = @bitCast(i32, r.random.scalar(u32));
-        const node = ctx.allocator.create(Queue(i32).Node{
+        const node = ctx.allocator.create(Queue(i32).Node) catch unreachable;
+        node.* = Queue(i32).Node{
             .prev = undefined,
             .next = undefined,
             .data = x,
-        }) catch unreachable;
+        };
         ctx.queue.put(node);
         _ = @atomicRmw(isize, &ctx.put_sum, builtin.AtomicRmwOp.Add, x, AtomicOrder.SeqCst);
     }
std/atomic/stack.zig
@@ -155,10 +155,11 @@ fn startPuts(ctx: *Context) u8 {
     while (put_count != 0) : (put_count -= 1) {
         std.os.time.sleep(1); // let the os scheduler be our fuzz
         const x = @bitCast(i32, r.random.scalar(u32));
-        const node = ctx.allocator.create(Stack(i32).Node{
+        const node = ctx.allocator.create(Stack(i32).Node) catch unreachable;
+        node.* = Stack(i32).Node{
             .next = undefined,
             .data = x,
-        }) catch unreachable;
+        };
         ctx.stack.push(node);
         _ = @atomicRmw(isize, &ctx.put_sum, builtin.AtomicRmwOp.Add, x, AtomicOrder.SeqCst);
     }
std/debug/index.zig
@@ -751,7 +751,7 @@ fn openSelfDebugInfoWindows(allocator: *mem.Allocator) !DebugInfo {
     const self_file = try os.openSelfExe();
     defer self_file.close();
 
-    const coff_obj = try allocator.createOne(coff.Coff);
+    const coff_obj = try allocator.create(coff.Coff);
     coff_obj.* = coff.Coff{
         .in_file = self_file,
         .allocator = allocator,
@@ -1036,7 +1036,7 @@ fn openSelfDebugInfoMacOs(allocator: *mem.Allocator) !DebugInfo {
             }
         }
     }
-    const sentinel = try allocator.createOne(macho.nlist_64);
+    const sentinel = try allocator.create(macho.nlist_64);
     sentinel.* = macho.nlist_64{
         .n_strx = 0,
         .n_type = 36,
@@ -1949,7 +1949,8 @@ fn scanAllCompileUnits(di: *DwarfInfo) !void {
 
         try di.dwarf_seekable_stream.seekTo(compile_unit_pos);
 
-        const compile_unit_die = try di.allocator().create(try parseDie(di, abbrev_table, is_64));
+        const compile_unit_die = try di.allocator().create(Die);
+        compile_unit_die.* = try parseDie(di, abbrev_table, is_64);
 
         if (compile_unit_die.tag_id != DW.TAG_compile_unit) return error.InvalidDebugInfo;
 
std/event/channel.zig
@@ -54,7 +54,8 @@ pub fn Channel(comptime T: type) type {
             const buffer_nodes = try loop.allocator.alloc(T, capacity);
             errdefer loop.allocator.free(buffer_nodes);
 
-            const self = try loop.allocator.create(SelfChannel{
+            const self = try loop.allocator.create(SelfChannel);
+            self.* = SelfChannel{
                 .loop = loop,
                 .buffer_len = 0,
                 .buffer_nodes = buffer_nodes,
@@ -66,7 +67,7 @@ pub fn Channel(comptime T: type) type {
                 .or_null_queue = std.atomic.Queue(*std.atomic.Queue(GetNode).Node).init(),
                 .get_count = 0,
                 .put_count = 0,
-            });
+            };
             errdefer loop.allocator.destroy(self);
 
             return self;
std/event/fs.zig
@@ -495,7 +495,7 @@ pub const CloseOperation = struct {
     };
 
     pub fn start(loop: *Loop) (error{OutOfMemory}!*CloseOperation) {
-        const self = try loop.allocator.createOne(CloseOperation);
+        const self = try loop.allocator.create(CloseOperation);
         self.* = CloseOperation{
             .loop = loop,
             .os_data = switch (builtin.os) {
@@ -787,7 +787,7 @@ pub fn Watch(comptime V: type) type {
                 },
 
                 builtin.Os.windows => {
-                    const self = try loop.allocator.createOne(Self);
+                    const self = try loop.allocator.create(Self);
                     errdefer loop.allocator.destroy(self);
                     self.* = Self{
                         .channel = channel,
@@ -802,7 +802,7 @@ pub fn Watch(comptime V: type) type {
                 },
 
                 builtin.Os.macosx, builtin.Os.freebsd => {
-                    const self = try loop.allocator.createOne(Self);
+                    const self = try loop.allocator.create(Self);
                     errdefer loop.allocator.destroy(self);
 
                     self.* = Self{
@@ -1068,7 +1068,7 @@ pub fn Watch(comptime V: type) type {
                 }
             } else {
                 errdefer _ = self.os_data.dir_table.remove(dirname);
-                const dir = try self.channel.loop.allocator.createOne(OsData.Dir);
+                const dir = try self.channel.loop.allocator.create(OsData.Dir);
                 errdefer self.channel.loop.allocator.destroy(dir);
 
                 dir.* = OsData.Dir{
std/event/group.zig
@@ -42,10 +42,11 @@ pub fn Group(comptime ReturnType: type) type {
 
         /// Add a promise to the group. Thread-safe.
         pub fn add(self: *Self, handle: promise->ReturnType) (error{OutOfMemory}!void) {
-            const node = try self.lock.loop.allocator.create(Stack.Node{
+            const node = try self.lock.loop.allocator.create(Stack.Node);
+            node.* = Stack.Node{
                 .next = undefined,
                 .data = handle,
-            });
+            };
             self.alloc_stack.push(node);
         }
 
std/os/child_process.zig
@@ -88,7 +88,8 @@ pub const ChildProcess = struct {
     /// First argument in argv is the executable.
     /// On success must call deinit.
     pub fn init(argv: []const []const u8, allocator: *mem.Allocator) !*ChildProcess {
-        const child = try allocator.create(ChildProcess{
+        const child = try allocator.create(ChildProcess);
+        child.* = ChildProcess{
             .allocator = allocator,
             .argv = argv,
             .pid = undefined,
@@ -109,7 +110,7 @@ pub const ChildProcess = struct {
             .stdin_behavior = StdIo.Inherit,
             .stdout_behavior = StdIo.Inherit,
             .stderr_behavior = StdIo.Inherit,
-        });
+        };
         errdefer allocator.destroy(child);
         return child;
     }
std/os/index.zig
@@ -3047,7 +3047,8 @@ pub fn spawnThread(context: var, comptime startFn: var) SpawnThreadError!*Thread
         const bytes_ptr = windows.HeapAlloc(heap_handle, 0, byte_count) orelse return SpawnThreadError.OutOfMemory;
         errdefer assert(windows.HeapFree(heap_handle, 0, bytes_ptr) != 0);
         const bytes = @ptrCast([*]u8, bytes_ptr)[0..byte_count];
-        const outer_context = std.heap.FixedBufferAllocator.init(bytes).allocator.create(WinThread.OuterContext{
+        const outer_context = std.heap.FixedBufferAllocator.init(bytes).allocator.create(WinThread.OuterContext) catch unreachable;
+        outer_context.* = WinThread.OuterContext{
             .thread = Thread{
                 .data = Thread.Data{
                     .heap_handle = heap_handle,
@@ -3056,7 +3057,7 @@ pub fn spawnThread(context: var, comptime startFn: var) SpawnThreadError!*Thread
                 },
             },
             .inner = context,
-        }) catch unreachable;
+        };
 
         const parameter = if (@sizeOf(Context) == 0) null else @ptrCast(*c_void, &outer_context.inner);
         outer_context.thread.data.handle = windows.CreateThread(null, default_stack_size, WinThread.threadMain, parameter, 0, null) orelse {
std/zig/parse.zig
@@ -17,14 +17,15 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
     defer stack.deinit();
 
     const arena = &tree_arena.allocator;
-    const root_node = try arena.create(ast.Node.Root{
+    const root_node = try arena.create(ast.Node.Root);
+    root_node.* = ast.Node.Root{
         .base = ast.Node{ .id = ast.Node.Id.Root },
         .decls = ast.Node.Root.DeclList.init(arena),
         .doc_comments = null,
         .shebang = null,
         // initialized when we get the eof token
         .eof_token = undefined,
-    });
+    };
 
     var tree = ast.Tree{
         .source = source,
@@ -75,20 +76,22 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
                     Token.Id.Keyword_test => {
                         stack.append(State.TopLevel) catch unreachable;
 
-                        const block = try arena.create(ast.Node.Block{
+                        const block = try arena.create(ast.Node.Block);
+                        block.* = ast.Node.Block{
                             .base = ast.Node{ .id = ast.Node.Id.Block },
                             .label = null,
                             .lbrace = undefined,
                             .statements = ast.Node.Block.StatementList.init(arena),
                             .rbrace = undefined,
-                        });
-                        const test_node = try arena.create(ast.Node.TestDecl{
+                        };
+                        const test_node = try arena.create(ast.Node.TestDecl);
+                        test_node.* = ast.Node.TestDecl{
                             .base = ast.Node{ .id = ast.Node.Id.TestDecl },
                             .doc_comments = comments,
                             .test_token = token_index,
                             .name = undefined,
                             .body_node = &block.base,
-                        });
+                        };
                         try root_node.decls.push(&test_node.base);
                         try stack.append(State{ .Block = block });
                         try stack.append(State{
@@ -119,19 +122,21 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
                         continue;
                     },
                     Token.Id.Keyword_comptime => {
-                        const block = try arena.create(ast.Node.Block{
+                        const block = try arena.create(ast.Node.Block);
+                        block.* = ast.Node.Block{
                             .base = ast.Node{ .id = ast.Node.Id.Block },
                             .label = null,
                             .lbrace = undefined,
                             .statements = ast.Node.Block.StatementList.init(arena),
                             .rbrace = undefined,
-                        });
-                        const node = try arena.create(ast.Node.Comptime{
+                        };
+                        const node = try arena.create(ast.Node.Comptime);
+                        node.* = ast.Node.Comptime{
                             .base = ast.Node{ .id = ast.Node.Id.Comptime },
                             .comptime_token = token_index,
                             .expr = &block.base,
                             .doc_comments = comments,
-                        });
+                        };
                         try root_node.decls.push(&node.base);
 
                         stack.append(State.TopLevel) catch unreachable;
@@ -235,14 +240,15 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
                             return tree;
                         }
 
-                        const node = try arena.create(ast.Node.Use{
+                        const node = try arena.create(ast.Node.Use);
+                        node.* = ast.Node.Use{
                             .base = ast.Node{ .id = ast.Node.Id.Use },
                             .use_token = token_index,
                             .visib_token = ctx.visib_token,
                             .expr = undefined,
                             .semicolon_token = undefined,
                             .doc_comments = ctx.comments,
-                        });
+                        };
                         try ctx.decls.push(&node.base);
 
                         stack.append(State{
@@ -276,7 +282,8 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
                         continue;
                     },
                     Token.Id.Keyword_fn, Token.Id.Keyword_nakedcc, Token.Id.Keyword_stdcallcc, Token.Id.Keyword_async => {
-                        const fn_proto = try arena.create(ast.Node.FnProto{
+                        const fn_proto = try arena.create(ast.Node.FnProto);
+                        fn_proto.* = ast.Node.FnProto{
                             .base = ast.Node{ .id = ast.Node.Id.FnProto },
                             .doc_comments = ctx.comments,
                             .visib_token = ctx.visib_token,
@@ -292,7 +299,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
                             .lib_name = ctx.lib_name,
                             .align_expr = null,
                             .section_expr = null,
-                        });
+                        };
                         try ctx.decls.push(&fn_proto.base);
                         stack.append(State{ .FnDef = fn_proto }) catch unreachable;
                         try stack.append(State{ .FnProto = fn_proto });
@@ -309,12 +316,13 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
                                 continue;
                             },
                             Token.Id.Keyword_async => {
-                                const async_node = try arena.create(ast.Node.AsyncAttribute{
+                                const async_node = try arena.create(ast.Node.AsyncAttribute);
+                                async_node.* = ast.Node.AsyncAttribute{
                                     .base = ast.Node{ .id = ast.Node.Id.AsyncAttribute },
                                     .async_token = token_index,
                                     .allocator_type = null,
                                     .rangle_bracket = null,
-                                });
+                                };
                                 fn_proto.async_attr = async_node;
 
                                 try stack.append(State{
@@ -341,13 +349,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
             },
             State.TopLevelExternOrField => |ctx| {
                 if (eatToken(&tok_it, &tree, Token.Id.Identifier)) |identifier| {
-                    const node = try arena.create(ast.Node.StructField{
+                    const node = try arena.create(ast.Node.StructField);
+                    node.* = ast.Node.StructField{
                         .base = ast.Node{ .id = ast.Node.Id.StructField },
                         .doc_comments = ctx.comments,
                         .visib_token = ctx.visib_token,
                         .name_token = identifier,
                         .type_expr = undefined,
-                    });
+                    };
                     const node_ptr = try ctx.container_decl.fields_and_decls.addOne();
                     node_ptr.* = &node.base;
 
@@ -391,7 +400,8 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
                 const token = nextToken(&tok_it, &tree);
                 const token_index = token.index;
                 const token_ptr = token.ptr;
-                const node = try arena.create(ast.Node.ContainerDecl{
+                const node = try arena.create(ast.Node.ContainerDecl);
+                node.* = ast.Node.ContainerDecl{
                     .base = ast.Node{ .id = ast.Node.Id.ContainerDecl },
                     .layout_token = ctx.layout_token,
                     .kind_token = switch (token_ptr.id) {
@@ -405,7 +415,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
                     .fields_and_decls = ast.Node.ContainerDecl.DeclList.init(arena),
                     .lbrace_token = undefined,
                     .rbrace_token = undefined,
-                });
+                };
                 ctx.opt_ctx.store(&node.base);
 
                 stack.append(State{ .ContainerDecl = node }) catch unreachable;
@@ -464,13 +474,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
                     Token.Id.Identifier => {
                         switch (tree.tokens.at(container_decl.kind_token).id) {
                             Token.Id.Keyword_struct => {
-                                const node = try arena.create(ast.Node.StructField{
+                                const node = try arena.create(ast.Node.StructField);
+                                node.* = ast.Node.StructField{
                                     .base = ast.Node{ .id = ast.Node.Id.StructField },
                                     .doc_comments = comments,
                                     .visib_token = null,
                                     .name_token = token_index,
                                     .type_expr = undefined,
-                                });
+                                };
                                 const node_ptr = try container_decl.fields_and_decls.addOne();
                                 node_ptr.* = &node.base;
 
@@ -485,13 +496,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
                                 continue;
                             },
                             Token.Id.Keyword_union => {
-                                const node = try arena.create(ast.Node.UnionTag{
+                                const node = try arena.create(ast.Node.UnionTag);
+                                node.* = ast.Node.UnionTag{
                                     .base = ast.Node{ .id = ast.Node.Id.UnionTag },
                                     .name_token = token_index,
                                     .type_expr = null,
                                     .value_expr = null,
                                     .doc_comments = comments,
-                                });
+                                };
                                 try container_decl.fields_and_decls.push(&node.base);
 
                                 try stack.append(State{
@@ -506,12 +518,13 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
                                 continue;
                             },
                             Token.Id.Keyword_enum => {
-                                const node = try arena.create(ast.Node.EnumTag{
+                                const node = try arena.create(ast.Node.EnumTag);
+                                node.* = ast.Node.EnumTag{
                                     .base = ast.Node{ .id = ast.Node.Id.EnumTag },
                                     .name_token = token_index,
                                     .value = null,
                                     .doc_comments = comments,
-                                });
+                                };
                                 try container_decl.fields_and_decls.push(&node.base);
 
                                 try stack.append(State{
@@ -593,7 +606,8 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
             },
 
             State.VarDecl => |ctx| {
-                const var_decl = try arena.create(ast.Node.VarDecl{
+                const var_decl = try arena.create(ast.Node.VarDecl);
+                var_decl.* = ast.Node.VarDecl{
                     .base = ast.Node{ .id = ast.Node.Id.VarDecl },
                     .doc_comments = ctx.comments,
                     .visib_token = ctx.visib_token,
@@ -609,7 +623,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
                     .name_token = undefined,
                     .eq_token = undefined,
                     .semicolon_token = undefined,
-                });
+                };
                 try ctx.list.push(&var_decl.base);
 
                 try stack.append(State{ .VarDeclAlign = var_decl });
@@ -708,13 +722,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
                 const token_ptr = token.ptr;
                 switch (token_ptr.id) {
                     Token.Id.LBrace => {
-                        const block = try arena.create(ast.Node.Block{
+                        const block = try arena.create(ast.Node.Block);
+                        block.* = ast.Node.Block{
                             .base = ast.Node{ .id = ast.Node.Id.Block },
                             .label = null,
                             .lbrace = token_index,
                             .statements = ast.Node.Block.StatementList.init(arena),
                             .rbrace = undefined,
-                        });
+                        };
                         fn_proto.body_node = &block.base;
                         stack.append(State{ .Block = block }) catch unreachable;
                         continue;
@@ -770,10 +785,11 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
                         // TODO: this is a special case. Remove this when #760 is fixed
                         if (token_ptr.id == Token.Id.Keyword_anyerror) {
                             if (tok_it.peek().?.id == Token.Id.LBrace) {
-                                const error_type_node = try arena.create(ast.Node.ErrorType{
+                                const error_type_node = try arena.create(ast.Node.ErrorType);
+                                error_type_node.* = ast.Node.ErrorType{
                                     .base = ast.Node{ .id = ast.Node.Id.ErrorType },
                                     .token = token_index,
-                                });
+                                };
                                 fn_proto.return_type = ast.Node.FnProto.ReturnType{ .Explicit = &error_type_node.base };
                                 continue;
                             }
@@ -791,14 +807,15 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
                 if (eatToken(&tok_it, &tree, Token.Id.RParen)) |_| {
                     continue;
                 }
-                const param_decl = try arena.create(ast.Node.ParamDecl{
+                const param_decl = try arena.create(ast.Node.ParamDecl);
+                param_decl.* = ast.Node.ParamDecl{
                     .base = ast.Node{ .id = ast.Node.Id.ParamDecl },
                     .comptime_token = null,
                     .noalias_token = null,
                     .name_token = null,
                     .type_node = undefined,
                     .var_args_token = null,
-                });
+                };
                 try fn_proto.params.push(&param_decl.base);
 
                 stack.append(State{
@@ -877,13 +894,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
                 const token_ptr = token.ptr;
                 switch (token_ptr.id) {
                     Token.Id.LBrace => {
-                        const block = try arena.create(ast.Node.Block{
+                        const block = try arena.create(ast.Node.Block);
+                        block.* = ast.Node.Block{
                             .base = ast.Node{ .id = ast.Node.Id.Block },
                             .label = ctx.label,
                             .lbrace = token_index,
                             .statements = ast.Node.Block.StatementList.init(arena),
                             .rbrace = undefined,
-                        });
+                        };
                         ctx.opt_ctx.store(&block.base);
                         stack.append(State{ .Block = block }) catch unreachable;
                         continue;
@@ -970,7 +988,8 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
                 }
             },
             State.While => |ctx| {
-                const node = try arena.create(ast.Node.While{
+                const node = try arena.create(ast.Node.While);
+                node.* = ast.Node.While{
                     .base = ast.Node{ .id = ast.Node.Id.While },
                     .label = ctx.label,
                     .inline_token = ctx.inline_token,
@@ -980,7 +999,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
                     .continue_expr = null,
                     .body = undefined,
                     .@"else" = null,
-                });
+                };
                 ctx.opt_ctx.store(&node.base);
                 stack.append(State{ .Else = &node.@"else" }) catch unreachable;
                 try stack.append(State{ .Expression = OptionalCtx{ .Required = &node.body } });
@@ -999,7 +1018,8 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
                 continue;
             },
             State.For => |ctx| {
-                const node = try arena.create(ast.Node.For{
+                const node = try arena.create(ast.Node.For);
+                node.* = ast.Node.For{
                     .base = ast.Node{ .id = ast.Node.Id.For },
                     .label = ctx.label,
                     .inline_token = ctx.inline_token,
@@ -1008,7 +1028,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
                     .payload = null,
                     .body = undefined,
                     .@"else" = null,
-                });
+                };
                 ctx.opt_ctx.store(&node.base);
                 stack.append(State{ .Else = &node.@"else" }) catch unreachable;
                 try stack.append(State{ .Expression = OptionalCtx{ .Required = &node.body } });
@@ -1020,12 +1040,13 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
             },
             State.Else => |dest| {
                 if (eatToken(&tok_it, &tree, Token.Id.Keyword_else)) |else_token| {
-                    const node = try arena.create(ast.Node.Else{
+                    const node = try arena.create(ast.Node.Else);
+                    node.* = ast.Node.Else{
                         .base = ast.Node{ .id = ast.Node.Id.Else },
                         .else_token = else_token,
                         .payload = null,
                         .body = undefined,
-                    });
+                    };
                     dest.* = node;
 
                     stack.append(State{ .Expression = OptionalCtx{ .Required = &node.body } }) catch unreachable;
@@ -1083,11 +1104,12 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
                         continue;
                     },
                     Token.Id.Keyword_defer, Token.Id.Keyword_errdefer => {
-                        const node = try arena.create(ast.Node.Defer{
+                        const node = try arena.create(ast.Node.Defer);
+                        node.* = ast.Node.Defer{
                             .base = ast.Node{ .id = ast.Node.Id.Defer },
                             .defer_token = token_index,
                             .expr = undefined,
-                        });
+                        };
                         const node_ptr = try block.statements.addOne();
                         node_ptr.* = &node.base;
 
@@ -1096,13 +1118,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
                         continue;
                     },
                     Token.Id.LBrace => {
-                        const inner_block = try arena.create(ast.Node.Block{
+                        const inner_block = try arena.create(ast.Node.Block);
+                        inner_block.* = ast.Node.Block{
                             .base = ast.Node{ .id = ast.Node.Id.Block },
                             .label = null,
                             .lbrace = token_index,
                             .statements = ast.Node.Block.StatementList.init(arena),
                             .rbrace = undefined,
-                        });
+                        };
                         try block.statements.push(&inner_block.base);
 
                         stack.append(State{ .Block = inner_block }) catch unreachable;
@@ -1164,14 +1187,15 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
                     continue;
                 }
 
-                const node = try arena.create(ast.Node.AsmOutput{
+                const node = try arena.create(ast.Node.AsmOutput);
+                node.* = ast.Node.AsmOutput{
                     .base = ast.Node{ .id = ast.Node.Id.AsmOutput },
                     .lbracket = lbracket_index,
                     .symbolic_name = undefined,
                     .constraint = undefined,
                     .kind = undefined,
                     .rparen = undefined,
-                });
+                };
                 try items.push(node);
 
                 stack.append(State{ .AsmOutputItems = items }) catch unreachable;
@@ -1218,14 +1242,15 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
                     continue;
                 }
 
-                const node = try arena.create(ast.Node.AsmInput{
+                const node = try arena.create(ast.Node.AsmInput);
+                node.* = ast.Node.AsmInput{
                     .base = ast.Node{ .id = ast.Node.Id.AsmInput },
                     .lbracket = lbracket_index,
                     .symbolic_name = undefined,
                     .constraint = undefined,
                     .expr = undefined,
                     .rparen = undefined,
-                });
+                };
                 try items.push(node);
 
                 stack.append(State{ .AsmInputItems = items }) catch unreachable;
@@ -1283,12 +1308,13 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
                     continue;
                 }
 
-                const node = try arena.create(ast.Node.FieldInitializer{
+                const node = try arena.create(ast.Node.FieldInitializer);
+                node.* = ast.Node.FieldInitializer{
                     .base = ast.Node{ .id = ast.Node.Id.FieldInitializer },
                     .period_token = undefined,
                     .name_token = undefined,
                     .expr = undefined,
-                });
+                };
                 try list_state.list.push(&node.base);
 
                 stack.append(State{ .FieldInitListCommaOrEnd = list_state }) catch unreachable;
@@ -1390,13 +1416,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
                 }
 
                 const comments = try eatDocComments(arena, &tok_it, &tree);
-                const node = try arena.create(ast.Node.SwitchCase{
+                const node = try arena.create(ast.Node.SwitchCase);
+                node.* = ast.Node.SwitchCase{
                     .base = ast.Node{ .id = ast.Node.Id.SwitchCase },
                     .items = ast.Node.SwitchCase.ItemList.init(arena),
                     .payload = null,
                     .expr = undefined,
                     .arrow_token = undefined,
-                });
+                };
                 try list_state.list.push(&node.base);
                 try stack.append(State{ .SwitchCaseCommaOrEnd = list_state });
                 try stack.append(State{ .AssignmentExpressionBegin = OptionalCtx{ .Required = &node.expr } });
@@ -1427,10 +1454,11 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
                 const token_index = token.index;
                 const token_ptr = token.ptr;
                 if (token_ptr.id == Token.Id.Keyword_else) {
-                    const else_node = try arena.create(ast.Node.SwitchElse{
+                    const else_node = try arena.create(ast.Node.SwitchElse);
+                    else_node.* = ast.Node.SwitchElse{
                         .base = ast.Node{ .id = ast.Node.Id.SwitchElse },
                         .token = token_index,
-                    });
+                    };
                     try switch_case.items.push(&else_node.base);
 
                     try stack.append(State{
@@ -1537,7 +1565,8 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
 
             State.ExternType => |ctx| {
                 if (eatToken(&tok_it, &tree, Token.Id.Keyword_fn)) |fn_token| {
-                    const fn_proto = try arena.create(ast.Node.FnProto{
+                    const fn_proto = try arena.create(ast.Node.FnProto);
+                    fn_proto.* = ast.Node.FnProto{
                         .base = ast.Node{ .id = ast.Node.Id.FnProto },
                         .doc_comments = ctx.comments,
                         .visib_token = null,
@@ -1553,7 +1582,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
                         .lib_name = null,
                         .align_expr = null,
                         .section_expr = null,
-                    });
+                    };
                     ctx.opt_ctx.store(&fn_proto.base);
                     stack.append(State{ .FnProto = fn_proto }) catch unreachable;
                     continue;
@@ -1711,12 +1740,13 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
                     continue;
                 }
 
-                const node = try arena.create(ast.Node.Payload{
+                const node = try arena.create(ast.Node.Payload);
+                node.* = ast.Node.Payload{
                     .base = ast.Node{ .id = ast.Node.Id.Payload },
                     .lpipe = token_index,
                     .error_symbol = undefined,
                     .rpipe = undefined,
-                });
+                };
                 opt_ctx.store(&node.base);
 
                 stack.append(State{
@@ -1747,13 +1777,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
                     continue;
                 }
 
-                const node = try arena.create(ast.Node.PointerPayload{
+                const node = try arena.create(ast.Node.PointerPayload);
+                node.* = ast.Node.PointerPayload{
                     .base = ast.Node{ .id = ast.Node.Id.PointerPayload },
                     .lpipe = token_index,
                     .ptr_token = null,
                     .value_symbol = undefined,
                     .rpipe = undefined,
-                });
+                };
                 opt_ctx.store(&node.base);
 
                 try stack.append(State{
@@ -1790,14 +1821,15 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
                     continue;
                 }
 
-                const node = try arena.create(ast.Node.PointerIndexPayload{
+                const node = try arena.create(ast.Node.PointerIndexPayload);
+                node.* = ast.Node.PointerIndexPayload{
                     .base = ast.Node{ .id = ast.Node.Id.PointerIndexPayload },
                     .lpipe = token_index,
                     .ptr_token = null,
                     .value_symbol = undefined,
                     .index_symbol = null,
                     .rpipe = undefined,
-                });
+                };
                 opt_ctx.store(&node.base);
 
                 stack.append(State{
@@ -1824,12 +1856,13 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
                 const token_ptr = token.ptr;
                 switch (token_ptr.id) {
                     Token.Id.Keyword_return, Token.Id.Keyword_break, Token.Id.Keyword_continue => {
-                        const node = try arena.create(ast.Node.ControlFlowExpression{
+                        const node = try arena.create(ast.Node.ControlFlowExpression);
+                        node.* = ast.Node.ControlFlowExpression{
                             .base = ast.Node{ .id = ast.Node.Id.ControlFlowExpression },
                             .ltoken = token_index,
                             .kind = undefined,
                             .rhs = null,
-                        });
+                        };
                         opt_ctx.store(&node.base);
 
                         stack.append(State{ .Expression = OptionalCtx{ .Optional = &node.rhs } }) catch unreachable;
@@ -1853,7 +1886,8 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
                         continue;
                     },
                     Token.Id.Keyword_try, Token.Id.Keyword_cancel, Token.Id.Keyword_resume => {
-                        const node = try arena.create(ast.Node.PrefixOp{
+                        const node = try arena.create(ast.Node.PrefixOp);
+                        node.* = ast.Node.PrefixOp{
                             .base = ast.Node{ .id = ast.Node.Id.PrefixOp },
                             .op_token = token_index,
                             .op = switch (token_ptr.id) {
@@ -1863,7 +1897,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
                                 else => unreachable,
                             },
                             .rhs = undefined,
-                        });
+                        };
                         opt_ctx.store(&node.base);
 
                         stack.append(State{ .Expression = OptionalCtx{ .Required = &node.rhs } }) catch unreachable;
@@ -1887,13 +1921,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
                 const lhs = opt_ctx.get() orelse continue;
 
                 if (eatToken(&tok_it, &tree, Token.Id.Ellipsis3)) |ellipsis3| {
-                    const node = try arena.create(ast.Node.InfixOp{
+                    const node = try arena.create(ast.Node.InfixOp);
+                    node.* = ast.Node.InfixOp{
                         .base = ast.Node{ .id = ast.Node.Id.InfixOp },
                         .lhs = lhs,
                         .op_token = ellipsis3,
                         .op = ast.Node.InfixOp.Op.Range,
                         .rhs = undefined,
-                    });
+                    };
                     opt_ctx.store(&node.base);
                     stack.append(State{ .Expression = OptionalCtx{ .Required = &node.rhs } }) catch unreachable;
                     continue;
@@ -1912,13 +1947,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
                 const token_index = token.index;
                 const token_ptr = token.ptr;
                 if (tokenIdToAssignment(token_ptr.id)) |ass_id| {
-                    const node = try arena.create(ast.Node.InfixOp{
+                    const node = try arena.create(ast.Node.InfixOp);
+                    node.* = ast.Node.InfixOp{
                         .base = ast.Node{ .id = ast.Node.Id.InfixOp },
                         .lhs = lhs,
                         .op_token = token_index,
                         .op = ass_id,
                         .rhs = undefined,
-                    });
+                    };
                     opt_ctx.store(&node.base);
                     stack.append(State{ .AssignmentExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
                     try stack.append(State{ .Expression = OptionalCtx{ .Required = &node.rhs } });
@@ -1942,13 +1978,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
                 const token_index = token.index;
                 const token_ptr = token.ptr;
                 if (tokenIdToUnwrapExpr(token_ptr.id)) |unwrap_id| {
-                    const node = try arena.create(ast.Node.InfixOp{
+                    const node = try arena.create(ast.Node.InfixOp);
+                    node.* = ast.Node.InfixOp{
                         .base = ast.Node{ .id = ast.Node.Id.InfixOp },
                         .lhs = lhs,
                         .op_token = token_index,
                         .op = unwrap_id,
                         .rhs = undefined,
-                    });
+                    };
                     opt_ctx.store(&node.base);
 
                     stack.append(State{ .UnwrapExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
@@ -1974,13 +2011,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
                 const lhs = opt_ctx.get() orelse continue;
 
                 if (eatToken(&tok_it, &tree, Token.Id.Keyword_or)) |or_token| {
-                    const node = try arena.create(ast.Node.InfixOp{
+                    const node = try arena.create(ast.Node.InfixOp);
+                    node.* = ast.Node.InfixOp{
                         .base = ast.Node{ .id = ast.Node.Id.InfixOp },
                         .lhs = lhs,
                         .op_token = or_token,
                         .op = ast.Node.InfixOp.Op.BoolOr,
                         .rhs = undefined,
-                    });
+                    };
                     opt_ctx.store(&node.base);
                     stack.append(State{ .BoolOrExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
                     try stack.append(State{ .BoolAndExpressionBegin = OptionalCtx{ .Required = &node.rhs } });
@@ -1998,13 +2036,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
                 const lhs = opt_ctx.get() orelse continue;
 
                 if (eatToken(&tok_it, &tree, Token.Id.Keyword_and)) |and_token| {
-                    const node = try arena.create(ast.Node.InfixOp{
+                    const node = try arena.create(ast.Node.InfixOp);
+                    node.* = ast.Node.InfixOp{
                         .base = ast.Node{ .id = ast.Node.Id.InfixOp },
                         .lhs = lhs,
                         .op_token = and_token,
                         .op = ast.Node.InfixOp.Op.BoolAnd,
                         .rhs = undefined,
-                    });
+                    };
                     opt_ctx.store(&node.base);
                     stack.append(State{ .BoolAndExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
                     try stack.append(State{ .ComparisonExpressionBegin = OptionalCtx{ .Required = &node.rhs } });
@@ -2025,13 +2064,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
                 const token_index = token.index;
                 const token_ptr = token.ptr;
                 if (tokenIdToComparison(token_ptr.id)) |comp_id| {
-                    const node = try arena.create(ast.Node.InfixOp{
+                    const node = try arena.create(ast.Node.InfixOp);
+                    node.* = ast.Node.InfixOp{
                         .base = ast.Node{ .id = ast.Node.Id.InfixOp },
                         .lhs = lhs,
                         .op_token = token_index,
                         .op = comp_id,
                         .rhs = undefined,
-                    });
+                    };
                     opt_ctx.store(&node.base);
                     stack.append(State{ .ComparisonExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
                     try stack.append(State{ .BinaryOrExpressionBegin = OptionalCtx{ .Required = &node.rhs } });
@@ -2052,13 +2092,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
                 const lhs = opt_ctx.get() orelse continue;
 
                 if (eatToken(&tok_it, &tree, Token.Id.Pipe)) |pipe| {
-                    const node = try arena.create(ast.Node.InfixOp{
+                    const node = try arena.create(ast.Node.InfixOp);
+                    node.* = ast.Node.InfixOp{
                         .base = ast.Node{ .id = ast.Node.Id.InfixOp },
                         .lhs = lhs,
                         .op_token = pipe,
                         .op = ast.Node.InfixOp.Op.BitOr,
                         .rhs = undefined,
-                    });
+                    };
                     opt_ctx.store(&node.base);
                     stack.append(State{ .BinaryOrExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
                     try stack.append(State{ .BinaryXorExpressionBegin = OptionalCtx{ .Required = &node.rhs } });
@@ -2076,13 +2117,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
                 const lhs = opt_ctx.get() orelse continue;
 
                 if (eatToken(&tok_it, &tree, Token.Id.Caret)) |caret| {
-                    const node = try arena.create(ast.Node.InfixOp{
+                    const node = try arena.create(ast.Node.InfixOp);
+                    node.* = ast.Node.InfixOp{
                         .base = ast.Node{ .id = ast.Node.Id.InfixOp },
                         .lhs = lhs,
                         .op_token = caret,
                         .op = ast.Node.InfixOp.Op.BitXor,
                         .rhs = undefined,
-                    });
+                    };
                     opt_ctx.store(&node.base);
                     stack.append(State{ .BinaryXorExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
                     try stack.append(State{ .BinaryAndExpressionBegin = OptionalCtx{ .Required = &node.rhs } });
@@ -2100,13 +2142,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
                 const lhs = opt_ctx.get() orelse continue;
 
                 if (eatToken(&tok_it, &tree, Token.Id.Ampersand)) |ampersand| {
-                    const node = try arena.create(ast.Node.InfixOp{
+                    const node = try arena.create(ast.Node.InfixOp);
+                    node.* = ast.Node.InfixOp{
                         .base = ast.Node{ .id = ast.Node.Id.InfixOp },
                         .lhs = lhs,
                         .op_token = ampersand,
                         .op = ast.Node.InfixOp.Op.BitAnd,
                         .rhs = undefined,
-                    });
+                    };
                     opt_ctx.store(&node.base);
                     stack.append(State{ .BinaryAndExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
                     try stack.append(State{ .BitShiftExpressionBegin = OptionalCtx{ .Required = &node.rhs } });
@@ -2127,13 +2170,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
                 const token_index = token.index;
                 const token_ptr = token.ptr;
                 if (tokenIdToBitShift(token_ptr.id)) |bitshift_id| {
-                    const node = try arena.create(ast.Node.InfixOp{
+                    const node = try arena.create(ast.Node.InfixOp);
+                    node.* = ast.Node.InfixOp{
                         .base = ast.Node{ .id = ast.Node.Id.InfixOp },
                         .lhs = lhs,
                         .op_token = token_index,
                         .op = bitshift_id,
                         .rhs = undefined,
-                    });
+                    };
                     opt_ctx.store(&node.base);
                     stack.append(State{ .BitShiftExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
                     try stack.append(State{ .AdditionExpressionBegin = OptionalCtx{ .Required = &node.rhs } });
@@ -2157,13 +2201,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
                 const token_index = token.index;
                 const token_ptr = token.ptr;
                 if (tokenIdToAddition(token_ptr.id)) |add_id| {
-                    const node = try arena.create(ast.Node.InfixOp{
+                    const node = try arena.create(ast.Node.InfixOp);
+                    node.* = ast.Node.InfixOp{
                         .base = ast.Node{ .id = ast.Node.Id.InfixOp },
                         .lhs = lhs,
                         .op_token = token_index,
                         .op = add_id,
                         .rhs = undefined,
-                    });
+                    };
                     opt_ctx.store(&node.base);
                     stack.append(State{ .AdditionExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
                     try stack.append(State{ .MultiplyExpressionBegin = OptionalCtx{ .Required = &node.rhs } });
@@ -2187,13 +2232,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
                 const token_index = token.index;
                 const token_ptr = token.ptr;
                 if (tokenIdToMultiply(token_ptr.id)) |mult_id| {
-                    const node = try arena.create(ast.Node.InfixOp{
+                    const node = try arena.create(ast.Node.InfixOp);
+                    node.* = ast.Node.InfixOp{
                         .base = ast.Node{ .id = ast.Node.Id.InfixOp },
                         .lhs = lhs,
                         .op_token = token_index,
                         .op = mult_id,
                         .rhs = undefined,
-                    });
+                    };
                     opt_ctx.store(&node.base);
                     stack.append(State{ .MultiplyExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
                     try stack.append(State{ .CurlySuffixExpressionBegin = OptionalCtx{ .Required = &node.rhs } });
@@ -2215,12 +2261,13 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
                 const lhs = opt_ctx.get() orelse continue;
 
                 if (tok_it.peek().?.id == Token.Id.Period) {
-                    const node = try arena.create(ast.Node.SuffixOp{
+                    const node = try arena.create(ast.Node.SuffixOp);
+                    node.* = ast.Node.SuffixOp{
                         .base = ast.Node{ .id = ast.Node.Id.SuffixOp },
                         .lhs = lhs,
                         .op = ast.Node.SuffixOp.Op{ .StructInitializer = ast.Node.SuffixOp.Op.InitList.init(arena) },
                         .rtoken = undefined,
-                    });
+                    };
                     opt_ctx.store(&node.base);
 
                     stack.append(State{ .CurlySuffixExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
@@ -2234,12 +2281,13 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
                     continue;
                 }
 
-                const node = try arena.create(ast.Node.SuffixOp{
+                const node = try arena.create(ast.Node.SuffixOp);
+                node.* = ast.Node.SuffixOp{
                     .base = ast.Node{ .id = ast.Node.Id.SuffixOp },
                     .lhs = lhs,
                     .op = ast.Node.SuffixOp.Op{ .ArrayInitializer = ast.Node.SuffixOp.Op.InitList.init(arena) },
                     .rtoken = undefined,
-                });
+                };
                 opt_ctx.store(&node.base);
                 stack.append(State{ .CurlySuffixExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
                 try stack.append(State{ .IfToken = Token.Id.LBrace });
@@ -2263,13 +2311,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
                 const lhs = opt_ctx.get() orelse continue;
 
                 if (eatToken(&tok_it, &tree, Token.Id.Bang)) |bang| {
-                    const node = try arena.create(ast.Node.InfixOp{
+                    const node = try arena.create(ast.Node.InfixOp);
+                    node.* = ast.Node.InfixOp{
                         .base = ast.Node{ .id = ast.Node.Id.InfixOp },
                         .lhs = lhs,
                         .op_token = bang,
                         .op = ast.Node.InfixOp.Op.ErrorUnion,
                         .rhs = undefined,
-                    });
+                    };
                     opt_ctx.store(&node.base);
                     stack.append(State{ .TypeExprEnd = opt_ctx.toRequired() }) catch unreachable;
                     try stack.append(State{ .PrefixOpExpression = OptionalCtx{ .Required = &node.rhs } });
@@ -2282,22 +2331,24 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
                 const token_index = token.index;
                 const token_ptr = token.ptr;
                 if (tokenIdToPrefixOp(token_ptr.id)) |prefix_id| {
-                    var node = try arena.create(ast.Node.PrefixOp{
+                    var node = try arena.create(ast.Node.PrefixOp);
+                    node.* = ast.Node.PrefixOp{
                         .base = ast.Node{ .id = ast.Node.Id.PrefixOp },
                         .op_token = token_index,
                         .op = prefix_id,
                         .rhs = undefined,
-                    });
+                    };
                     opt_ctx.store(&node.base);
 
                     // Treat '**' token as two pointer types
                     if (token_ptr.id == Token.Id.AsteriskAsterisk) {
-                        const child = try arena.create(ast.Node.PrefixOp{
+                        const child = try arena.create(ast.Node.PrefixOp);
+                        child.* = ast.Node.PrefixOp{
                             .base = ast.Node{ .id = ast.Node.Id.PrefixOp },
                             .op_token = token_index,
                             .op = prefix_id,
                             .rhs = undefined,
-                        });
+                        };
                         node.rhs = &child.base;
                         node = child;
                     }
@@ -2316,12 +2367,13 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
 
             State.SuffixOpExpressionBegin => |opt_ctx| {
                 if (eatToken(&tok_it, &tree, Token.Id.Keyword_async)) |async_token| {
-                    const async_node = try arena.create(ast.Node.AsyncAttribute{
+                    const async_node = try arena.create(ast.Node.AsyncAttribute);
+                    async_node.* = ast.Node.AsyncAttribute{
                         .base = ast.Node{ .id = ast.Node.Id.AsyncAttribute },
                         .async_token = async_token,
                         .allocator_type = null,
                         .rangle_bracket = null,
-                    });
+                    };
                     stack.append(State{
                         .AsyncEnd = AsyncEndCtx{
                             .ctx = opt_ctx,
@@ -2347,7 +2399,8 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
                 const token_ptr = token.ptr;
                 switch (token_ptr.id) {
                     Token.Id.LParen => {
-                        const node = try arena.create(ast.Node.SuffixOp{
+                        const node = try arena.create(ast.Node.SuffixOp);
+                        node.* = ast.Node.SuffixOp{
                             .base = ast.Node{ .id = ast.Node.Id.SuffixOp },
                             .lhs = lhs,
                             .op = ast.Node.SuffixOp.Op{
@@ -2357,7 +2410,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
                                 },
                             },
                             .rtoken = undefined,
-                        });
+                        };
                         opt_ctx.store(&node.base);
 
                         stack.append(State{ .SuffixOpExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
@@ -2371,12 +2424,13 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
                         continue;
                     },
                     Token.Id.LBracket => {
-                        const node = try arena.create(ast.Node.SuffixOp{
+                        const node = try arena.create(ast.Node.SuffixOp);
+                        node.* = ast.Node.SuffixOp{
                             .base = ast.Node{ .id = ast.Node.Id.SuffixOp },
                             .lhs = lhs,
                             .op = ast.Node.SuffixOp.Op{ .ArrayAccess = undefined },
                             .rtoken = undefined,
-                        });
+                        };
                         opt_ctx.store(&node.base);
 
                         stack.append(State{ .SuffixOpExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
@@ -2386,34 +2440,37 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
                     },
                     Token.Id.Period => {
                         if (eatToken(&tok_it, &tree, Token.Id.Asterisk)) |asterisk_token| {
-                            const node = try arena.create(ast.Node.SuffixOp{
+                            const node = try arena.create(ast.Node.SuffixOp);
+                            node.* = ast.Node.SuffixOp{
                                 .base = ast.Node{ .id = ast.Node.Id.SuffixOp },
                                 .lhs = lhs,
                                 .op = ast.Node.SuffixOp.Op.Deref,
                                 .rtoken = asterisk_token,
-                            });
+                            };
                             opt_ctx.store(&node.base);
                             stack.append(State{ .SuffixOpExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
                             continue;
                         }
                         if (eatToken(&tok_it, &tree, Token.Id.QuestionMark)) |question_token| {
-                            const node = try arena.create(ast.Node.SuffixOp{
+                            const node = try arena.create(ast.Node.SuffixOp);
+                            node.* = ast.Node.SuffixOp{
                                 .base = ast.Node{ .id = ast.Node.Id.SuffixOp },
                                 .lhs = lhs,
                                 .op = ast.Node.SuffixOp.Op.UnwrapOptional,
                                 .rtoken = question_token,
-                            });
+                            };
                             opt_ctx.store(&node.base);
                             stack.append(State{ .SuffixOpExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
                             continue;
                         }
-                        const node = try arena.create(ast.Node.InfixOp{
+                        const node = try arena.create(ast.Node.InfixOp);
+                        node.* = ast.Node.InfixOp{
                             .base = ast.Node{ .id = ast.Node.Id.InfixOp },
                             .lhs = lhs,
                             .op_token = token_index,
                             .op = ast.Node.InfixOp.Op.Period,
                             .rhs = undefined,
-                        });
+                        };
                         opt_ctx.store(&node.base);
 
                         stack.append(State{ .SuffixOpExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
@@ -2467,11 +2524,12 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
                         continue;
                     },
                     Token.Id.Keyword_promise => {
-                        const node = try arena.create(ast.Node.PromiseType{
+                        const node = try arena.create(ast.Node.PromiseType);
+                        node.* = ast.Node.PromiseType{
                             .base = ast.Node{ .id = ast.Node.Id.PromiseType },
                             .promise_token = token.index,
                             .result = null,
-                        });
+                        };
                         opt_ctx.store(&node.base);
                         const next_token = nextToken(&tok_it, &tree);
                         const next_token_index = next_token.index;
@@ -2493,12 +2551,13 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
                         continue;
                     },
                     Token.Id.LParen => {
-                        const node = try arena.create(ast.Node.GroupedExpression{
+                        const node = try arena.create(ast.Node.GroupedExpression);
+                        node.* = ast.Node.GroupedExpression{
                             .base = ast.Node{ .id = ast.Node.Id.GroupedExpression },
                             .lparen = token.index,
                             .expr = undefined,
                             .rparen = undefined,
-                        });
+                        };
                         opt_ctx.store(&node.base);
 
                         stack.append(State{
@@ -2511,12 +2570,13 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
                         continue;
                     },
                     Token.Id.Builtin => {
-                        const node = try arena.create(ast.Node.BuiltinCall{
+                        const node = try arena.create(ast.Node.BuiltinCall);
+                        node.* = ast.Node.BuiltinCall{
                             .base = ast.Node{ .id = ast.Node.Id.BuiltinCall },
                             .builtin_token = token.index,
                             .params = ast.Node.BuiltinCall.ParamList.init(arena),
                             .rparen_token = undefined,
-                        });
+                        };
                         opt_ctx.store(&node.base);
 
                         stack.append(State{
@@ -2530,12 +2590,13 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
                         continue;
                     },
                     Token.Id.LBracket => {
-                        const node = try arena.create(ast.Node.PrefixOp{
+                        const node = try arena.create(ast.Node.PrefixOp);
+                        node.* = ast.Node.PrefixOp{
                             .base = ast.Node{ .id = ast.Node.Id.PrefixOp },
                             .op_token = token.index,
                             .op = undefined,
                             .rhs = undefined,
-                        });
+                        };
                         opt_ctx.store(&node.base);
 
                         stack.append(State{ .SliceOrArrayType = node }) catch unreachable;
@@ -2593,7 +2654,8 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
                         continue;
                     },
                     Token.Id.Keyword_fn => {
-                        const fn_proto = try arena.create(ast.Node.FnProto{
+                        const fn_proto = try arena.create(ast.Node.FnProto);
+                        fn_proto.* = ast.Node.FnProto{
                             .base = ast.Node{ .id = ast.Node.Id.FnProto },
                             .doc_comments = null,
                             .visib_token = null,
@@ -2609,13 +2671,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
                             .lib_name = null,
                             .align_expr = null,
                             .section_expr = null,
-                        });
+                        };
                         opt_ctx.store(&fn_proto.base);
                         stack.append(State{ .FnProto = fn_proto }) catch unreachable;
                         continue;
                     },
                     Token.Id.Keyword_nakedcc, Token.Id.Keyword_stdcallcc => {
-                        const fn_proto = try arena.create(ast.Node.FnProto{
+                        const fn_proto = try arena.create(ast.Node.FnProto);
+                        fn_proto.* = ast.Node.FnProto{
                             .base = ast.Node{ .id = ast.Node.Id.FnProto },
                             .doc_comments = null,
                             .visib_token = null,
@@ -2631,7 +2694,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
                             .lib_name = null,
                             .align_expr = null,
                             .section_expr = null,
-                        });
+                        };
                         opt_ctx.store(&fn_proto.base);
                         stack.append(State{ .FnProto = fn_proto }) catch unreachable;
                         try stack.append(State{
@@ -2643,7 +2706,8 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
                         continue;
                     },
                     Token.Id.Keyword_asm => {
-                        const node = try arena.create(ast.Node.Asm{
+                        const node = try arena.create(ast.Node.Asm);
+                        node.* = ast.Node.Asm{
                             .base = ast.Node{ .id = ast.Node.Id.Asm },
                             .asm_token = token.index,
                             .volatile_token = null,
@@ -2652,7 +2716,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
                             .inputs = ast.Node.Asm.InputList.init(arena),
                             .clobbers = ast.Node.Asm.ClobberList.init(arena),
                             .rparen = undefined,
-                        });
+                        };
                         opt_ctx.store(&node.base);
 
                         stack.append(State{
@@ -2701,13 +2765,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
 
             State.ErrorTypeOrSetDecl => |ctx| {
                 if (eatToken(&tok_it, &tree, Token.Id.LBrace) == null) {
-                    const node = try arena.create(ast.Node.InfixOp{
+                    const node = try arena.create(ast.Node.InfixOp);
+                    node.* = ast.Node.InfixOp{
                         .base = ast.Node{ .id = ast.Node.Id.InfixOp },
                         .lhs = &(try createLiteral(arena, ast.Node.ErrorType, ctx.error_token)).base,
                         .op_token = undefined,
                         .op = ast.Node.InfixOp.Op.Period,
                         .rhs = undefined,
-                    });
+                    };
                     ctx.opt_ctx.store(&node.base);
                     stack.append(State{ .Identifier = OptionalCtx{ .Required = &node.rhs } }) catch unreachable;
                     try stack.append(State{
@@ -2719,12 +2784,13 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
                     continue;
                 }
 
-                const node = try arena.create(ast.Node.ErrorSetDecl{
+                const node = try arena.create(ast.Node.ErrorSetDecl);
+                node.* = ast.Node.ErrorSetDecl{
                     .base = ast.Node{ .id = ast.Node.Id.ErrorSetDecl },
                     .error_token = ctx.error_token,
                     .decls = ast.Node.ErrorSetDecl.DeclList.init(arena),
                     .rbrace_token = undefined,
-                });
+                };
                 ctx.opt_ctx.store(&node.base);
 
                 stack.append(State{
@@ -2785,11 +2851,12 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
                     return tree;
                 }
 
-                const node = try arena.create(ast.Node.ErrorTag{
+                const node = try arena.create(ast.Node.ErrorTag);
+                node.* = ast.Node.ErrorTag{
                     .base = ast.Node{ .id = ast.Node.Id.ErrorTag },
                     .doc_comments = comments,
                     .name_token = ident_token_index,
-                });
+                };
                 node_ptr.* = &node.base;
                 continue;
             },
@@ -3129,10 +3196,11 @@ fn pushDocComment(arena: *mem.Allocator, line_comment: TokenIndex, result: *?*as
         if (result.*) |comment_node| {
             break :blk comment_node;
         } else {
-            const comment_node = try arena.create(ast.Node.DocComment{
+            const comment_node = try arena.create(ast.Node.DocComment);
+            comment_node.* = ast.Node.DocComment{
                 .base = ast.Node{ .id = ast.Node.Id.DocComment },
                 .lines = ast.Node.DocComment.LineList.init(arena),
-            });
+            };
             result.* = comment_node;
             break :blk comment_node;
         }
@@ -3158,10 +3226,11 @@ fn parseStringLiteral(arena: *mem.Allocator, tok_it: *ast.Tree.TokenList.Iterato
             return &(try createLiteral(arena, ast.Node.StringLiteral, token_index)).base;
         },
         Token.Id.MultilineStringLiteralLine => {
-            const node = try arena.create(ast.Node.MultilineStringLiteral{
+            const node = try arena.create(ast.Node.MultilineStringLiteral);
+            node.* = ast.Node.MultilineStringLiteral{
                 .base = ast.Node{ .id = ast.Node.Id.MultilineStringLiteral },
                 .lines = ast.Node.MultilineStringLiteral.LineList.init(arena),
-            });
+            };
             try node.lines.push(token_index);
             while (true) {
                 const multiline_str = nextToken(tok_it, tree);
@@ -3186,25 +3255,27 @@ fn parseStringLiteral(arena: *mem.Allocator, tok_it: *ast.Tree.TokenList.Iterato
 fn parseBlockExpr(stack: *std.ArrayList(State), arena: *mem.Allocator, ctx: OptionalCtx, token_ptr: Token, token_index: TokenIndex) !bool {
     switch (token_ptr.id) {
         Token.Id.Keyword_suspend => {
-            const node = try arena.create(ast.Node.Suspend{
+            const node = try arena.create(ast.Node.Suspend);
+            node.* = ast.Node.Suspend{
                 .base = ast.Node{ .id = ast.Node.Id.Suspend },
                 .suspend_token = token_index,
                 .body = null,
-            });
+            };
             ctx.store(&node.base);
 
             stack.append(State{ .SuspendBody = node }) catch unreachable;
             return true;
         },
         Token.Id.Keyword_if => {
-            const node = try arena.create(ast.Node.If{
+            const node = try arena.create(ast.Node.If);
+            node.* = ast.Node.If{
                 .base = ast.Node{ .id = ast.Node.Id.If },
                 .if_token = token_index,
                 .condition = undefined,
                 .payload = null,
                 .body = undefined,
                 .@"else" = null,
-            });
+            };
             ctx.store(&node.base);
 
             stack.append(State{ .Else = &node.@"else" }) catch unreachable;
@@ -3238,13 +3309,14 @@ fn parseBlockExpr(stack: *std.ArrayList(State), arena: *mem.Allocator, ctx: Opti
             return true;
         },
         Token.Id.Keyword_switch => {
-            const node = try arena.create(ast.Node.Switch{
+            const node = try arena.create(ast.Node.Switch);
+            node.* = ast.Node.Switch{
                 .base = ast.Node{ .id = ast.Node.Id.Switch },
                 .switch_token = token_index,
                 .expr = undefined,
                 .cases = ast.Node.Switch.CaseList.init(arena),
                 .rbrace = undefined,
-            });
+            };
             ctx.store(&node.base);
 
             stack.append(State{
@@ -3260,25 +3332,27 @@ fn parseBlockExpr(stack: *std.ArrayList(State), arena: *mem.Allocator, ctx: Opti
             return true;
         },
         Token.Id.Keyword_comptime => {
-            const node = try arena.create(ast.Node.Comptime{
+            const node = try arena.create(ast.Node.Comptime);
+            node.* = ast.Node.Comptime{
                 .base = ast.Node{ .id = ast.Node.Id.Comptime },
                 .comptime_token = token_index,
                 .expr = undefined,
                 .doc_comments = null,
-            });
+            };
             ctx.store(&node.base);
 
             try stack.append(State{ .Expression = OptionalCtx{ .Required = &node.expr } });
             return true;
         },
         Token.Id.LBrace => {
-            const block = try arena.create(ast.Node.Block{
+            const block = try arena.create(ast.Node.Block);
+            block.* = ast.Node.Block{
                 .base = ast.Node{ .id = ast.Node.Id.Block },
                 .label = null,
                 .lbrace = token_index,
                 .statements = ast.Node.Block.StatementList.init(arena),
                 .rbrace = undefined,
-            });
+            };
             ctx.store(&block.base);
             stack.append(State{ .Block = block }) catch unreachable;
             return true;
@@ -3412,10 +3486,12 @@ fn tokenIdToPrefixOp(id: Token.Id) ?ast.Node.PrefixOp.Op {
 }
 
 fn createLiteral(arena: *mem.Allocator, comptime T: type, token_index: TokenIndex) !*T {
-    return arena.create(T{
+    const result = try arena.create(T);
+    result.* = T{
         .base = ast.Node{ .id = ast.Node.typeToId(T) },
         .token = token_index,
-    });
+    };
+    return result;
 }
 
 fn createToCtxLiteral(arena: *mem.Allocator, opt_ctx: OptionalCtx, comptime T: type, token_index: TokenIndex) !*T {
std/build.zig
@@ -89,7 +89,7 @@ pub const Builder = struct {
     };
 
     pub fn init(allocator: *Allocator, zig_exe: []const u8, build_root: []const u8, cache_root: []const u8) Builder {
-        const env_map = allocator.createOne(BufMap) catch unreachable;
+        const env_map = allocator.create(BufMap) catch unreachable;
         env_map.* = os.getEnvMap(allocator) catch unreachable;
         var self = Builder{
             .zig_exe = zig_exe,
@@ -170,7 +170,8 @@ pub const Builder = struct {
     }
 
     pub fn addTest(self: *Builder, root_src: []const u8) *TestStep {
-        const test_step = self.allocator.create(TestStep.init(self, root_src)) catch unreachable;
+        const test_step = self.allocator.create(TestStep) catch unreachable;
+        test_step.* = TestStep.init(self, root_src);
         return test_step;
     }
 
@@ -202,18 +203,21 @@ pub const Builder = struct {
     }
 
     pub fn addWriteFile(self: *Builder, file_path: []const u8, data: []const u8) *WriteFileStep {
-        const write_file_step = self.allocator.create(WriteFileStep.init(self, file_path, data)) catch unreachable;
+        const write_file_step = self.allocator.create(WriteFileStep) catch unreachable;
+        write_file_step.* = WriteFileStep.init(self, file_path, data);
         return write_file_step;
     }
 
     pub fn addLog(self: *Builder, comptime format: []const u8, args: ...) *LogStep {
         const data = self.fmt(format, args);
-        const log_step = self.allocator.create(LogStep.init(self, data)) catch unreachable;
+        const log_step = self.allocator.create(LogStep) catch unreachable;
+        log_step.* = LogStep.init(self, data);
         return log_step;
     }
 
     pub fn addRemoveDirTree(self: *Builder, dir_path: []const u8) *RemoveDirStep {
-        const remove_dir_step = self.allocator.create(RemoveDirStep.init(self, dir_path)) catch unreachable;
+        const remove_dir_step = self.allocator.create(RemoveDirStep) catch unreachable;
+        remove_dir_step.* = RemoveDirStep.init(self, dir_path);
         return remove_dir_step;
     }
 
@@ -414,10 +418,11 @@ pub const Builder = struct {
     }
 
     pub fn step(self: *Builder, name: []const u8, description: []const u8) *Step {
-        const step_info = self.allocator.create(TopLevelStep{
+        const step_info = self.allocator.create(TopLevelStep) catch unreachable;
+        step_info.* = TopLevelStep{
             .step = Step.initNoOp(name, self.allocator),
             .description = description,
-        }) catch unreachable;
+        };
         self.top_level_steps.append(step_info) catch unreachable;
         return &step_info.step;
     }
@@ -616,7 +621,8 @@ pub const Builder = struct {
         const full_dest_path = os.path.resolve(self.allocator, self.prefix, dest_rel_path) catch unreachable;
         self.pushInstalledFile(full_dest_path);
 
-        const install_step = self.allocator.create(InstallFileStep.init(self, src_path, full_dest_path)) catch unreachable;
+        const install_step = self.allocator.create(InstallFileStep) catch unreachable;
+        install_step.* = InstallFileStep.init(self, src_path, full_dest_path);
         return install_step;
     }
 
@@ -865,43 +871,51 @@ pub const LibExeObjStep = struct {
     };
 
     pub fn createSharedLibrary(builder: *Builder, name: []const u8, root_src: ?[]const u8, ver: Version) *LibExeObjStep {
-        const self = builder.allocator.create(initExtraArgs(builder, name, root_src, Kind.Lib, false, ver)) catch unreachable;
+        const self = builder.allocator.create(LibExeObjStep) catch unreachable;
+        self.* = initExtraArgs(builder, name, root_src, Kind.Lib, false, ver);
         return self;
     }
 
     pub fn createCSharedLibrary(builder: *Builder, name: []const u8, version: Version) *LibExeObjStep {
-        const self = builder.allocator.create(initC(builder, name, Kind.Lib, version, false)) catch unreachable;
+        const self = builder.allocator.create(LibExeObjStep) catch unreachable;
+        self.* = initC(builder, name, Kind.Lib, version, false);
         return self;
     }
 
     pub fn createStaticLibrary(builder: *Builder, name: []const u8, root_src: ?[]const u8) *LibExeObjStep {
-        const self = builder.allocator.create(initExtraArgs(builder, name, root_src, Kind.Lib, true, builder.version(0, 0, 0))) catch unreachable;
+        const self = builder.allocator.create(LibExeObjStep) catch unreachable;
+        self.* = initExtraArgs(builder, name, root_src, Kind.Lib, true, builder.version(0, 0, 0));
         return self;
     }
 
     pub fn createCStaticLibrary(builder: *Builder, name: []const u8) *LibExeObjStep {
-        const self = builder.allocator.create(initC(builder, name, Kind.Lib, builder.version(0, 0, 0), true)) catch unreachable;
+        const self = builder.allocator.create(LibExeObjStep) catch unreachable;
+        self.* = initC(builder, name, Kind.Lib, builder.version(0, 0, 0), true);
         return self;
     }
 
     pub fn createObject(builder: *Builder, name: []const u8, root_src: []const u8) *LibExeObjStep {
-        const self = builder.allocator.create(initExtraArgs(builder, name, root_src, Kind.Obj, false, builder.version(0, 0, 0))) catch unreachable;
+        const self = builder.allocator.create(LibExeObjStep) catch unreachable;
+        self.* = initExtraArgs(builder, name, root_src, Kind.Obj, false, builder.version(0, 0, 0));
         return self;
     }
 
     pub fn createCObject(builder: *Builder, name: []const u8, src: []const u8) *LibExeObjStep {
-        const self = builder.allocator.create(initC(builder, name, Kind.Obj, builder.version(0, 0, 0), false)) catch unreachable;
+        const self = builder.allocator.create(LibExeObjStep) catch unreachable;
+        self.* = initC(builder, name, Kind.Obj, builder.version(0, 0, 0), false);
         self.object_src = src;
         return self;
     }
 
     pub fn createExecutable(builder: *Builder, name: []const u8, root_src: ?[]const u8, static: bool) *LibExeObjStep {
-        const self = builder.allocator.create(initExtraArgs(builder, name, root_src, Kind.Exe, static, builder.version(0, 0, 0))) catch unreachable;
+        const self = builder.allocator.create(LibExeObjStep) catch unreachable;
+        self.* = initExtraArgs(builder, name, root_src, Kind.Exe, static, builder.version(0, 0, 0));
         return self;
     }
 
     pub fn createCExecutable(builder: *Builder, name: []const u8) *LibExeObjStep {
-        const self = builder.allocator.create(initC(builder, name, Kind.Exe, builder.version(0, 0, 0), false)) catch unreachable;
+        const self = builder.allocator.create(LibExeObjStep) catch unreachable;
+        self.* = initC(builder, name, Kind.Exe, builder.version(0, 0, 0), false);
         return self;
     }
 
@@ -1914,13 +1928,14 @@ pub const CommandStep = struct {
 
     /// ::argv is copied.
     pub fn create(builder: *Builder, cwd: ?[]const u8, env_map: *const BufMap, argv: []const []const u8) *CommandStep {
-        const self = builder.allocator.create(CommandStep{
+        const self = builder.allocator.create(CommandStep) catch unreachable;
+        self.* = CommandStep{
             .builder = builder,
             .step = Step.init(argv[0], builder.allocator, make),
             .argv = builder.allocator.alloc([]u8, argv.len) catch unreachable,
             .cwd = cwd,
             .env_map = env_map,
-        }) catch unreachable;
+        };
 
         mem.copy([]const u8, self.argv, argv);
         self.step.name = self.argv[0];
@@ -1949,12 +1964,13 @@ const InstallArtifactStep = struct {
             LibExeObjStep.Kind.Exe => builder.exe_dir,
             LibExeObjStep.Kind.Lib => builder.lib_dir,
         };
-        const self = builder.allocator.create(Self{
+        const self = builder.allocator.create(Self) catch unreachable;
+        self.* = Self{
             .builder = builder,
             .step = Step.init(builder.fmt("install {}", artifact.step.name), builder.allocator, make),
             .artifact = artifact,
             .dest_file = os.path.join(builder.allocator, dest_dir, artifact.out_filename) catch unreachable,
-        }) catch unreachable;
+        };
         self.step.dependOn(&artifact.step);
         builder.pushInstalledFile(self.dest_file);
         if (self.artifact.kind == LibExeObjStep.Kind.Lib and !self.artifact.static) {
std/heap.zig
@@ -518,7 +518,8 @@ fn testAllocator(allocator: *mem.Allocator) !void {
     var slice = try allocator.alloc(*i32, 100);
     assert(slice.len == 100);
     for (slice) |*item, i| {
-        item.* = try allocator.create(@intCast(i32, i));
+        item.* = try allocator.create(i32);
+        item.*.* = @intCast(i32, i);
     }
 
     slice = try allocator.realloc(*i32, slice, 20000);
std/io.zig
@@ -944,12 +944,13 @@ pub const BufferedAtomicFile = struct {
 
     pub fn create(allocator: *mem.Allocator, dest_path: []const u8) !*BufferedAtomicFile {
         // TODO with well defined copy elision we don't need this allocation
-        var self = try allocator.create(BufferedAtomicFile{
+        var self = try allocator.create(BufferedAtomicFile);
+        self.* = BufferedAtomicFile{
             .atomic_file = undefined,
             .file_stream = undefined,
             .buffered_stream = undefined,
             .allocator = allocator,
-        });
+        };
         errdefer allocator.destroy(self);
 
         self.atomic_file = try os.AtomicFile.init(dest_path, os.File.default_mode);
std/linked_list.zig
@@ -190,7 +190,7 @@ pub fn LinkedList(comptime T: type) type {
         /// Returns:
         ///     A pointer to the new node.
         pub fn allocateNode(list: *Self, allocator: *Allocator) !*Node {
-            return allocator.create(Node(undefined));
+            return allocator.create(Node);
         }
 
         /// Deallocate a node.
std/mem.zig
@@ -36,20 +36,9 @@ pub const Allocator = struct {
     /// Guaranteed: `old_mem.len` is the same as what was returned from `allocFn` or `reallocFn`
     freeFn: fn (self: *Allocator, old_mem: []u8) void,
 
-    /// Call `destroy` with the result
-    /// TODO this is deprecated. use createOne instead
-    pub fn create(self: *Allocator, init: var) Error!*@typeOf(init) {
-        const T = @typeOf(init);
-        if (@sizeOf(T) == 0) return &(T{});
-        const slice = try self.alloc(T, 1);
-        const ptr = &slice[0];
-        ptr.* = init;
-        return ptr;
-    }
-
     /// Call `destroy` with the result.
     /// Returns undefined memory.
-    pub fn createOne(self: *Allocator, comptime T: type) Error!*T {
+    pub fn create(self: *Allocator, comptime T: type) Error!*T {
         if (@sizeOf(T) == 0) return &(T{});
         const slice = try self.alloc(T, 1);
         return &slice[0];
test/tests.zig
@@ -48,13 +48,14 @@ const test_targets = []TestTarget{
 const max_stdout_size = 1 * 1024 * 1024; // 1 MB
 
 pub fn addCompareOutputTests(b: *build.Builder, test_filter: ?[]const u8, modes: []const Mode) *build.Step {
-    const cases = b.allocator.create(CompareOutputContext{
+    const cases = b.allocator.create(CompareOutputContext) catch unreachable;
+    cases.* = CompareOutputContext{
         .b = b,
         .step = b.step("test-compare-output", "Run the compare output tests"),
         .test_index = 0,
         .test_filter = test_filter,
         .modes = modes,
-    }) catch unreachable;
+    };
 
     compare_output.addCases(cases);
 
@@ -62,13 +63,14 @@ pub fn addCompareOutputTests(b: *build.Builder, test_filter: ?[]const u8, modes:
 }
 
 pub fn addRuntimeSafetyTests(b: *build.Builder, test_filter: ?[]const u8, modes: []const Mode) *build.Step {
-    const cases = b.allocator.create(CompareOutputContext{
+    const cases = b.allocator.create(CompareOutputContext) catch unreachable;
+    cases.* = CompareOutputContext{
         .b = b,
         .step = b.step("test-runtime-safety", "Run the runtime safety tests"),
         .test_index = 0,
         .test_filter = test_filter,
         .modes = modes,
-    }) catch unreachable;
+    };
 
     runtime_safety.addCases(cases);
 
@@ -76,13 +78,14 @@ pub fn addRuntimeSafetyTests(b: *build.Builder, test_filter: ?[]const u8, modes:
 }
 
 pub fn addCompileErrorTests(b: *build.Builder, test_filter: ?[]const u8, modes: []const Mode) *build.Step {
-    const cases = b.allocator.create(CompileErrorContext{
+    const cases = b.allocator.create(CompileErrorContext) catch unreachable;
+    cases.* = CompileErrorContext{
         .b = b,
         .step = b.step("test-compile-errors", "Run the compile error tests"),
         .test_index = 0,
         .test_filter = test_filter,
         .modes = modes,
-    }) catch unreachable;
+    };
 
     compile_errors.addCases(cases);
 
@@ -90,13 +93,14 @@ pub fn addCompileErrorTests(b: *build.Builder, test_filter: ?[]const u8, modes:
 }
 
 pub fn addBuildExampleTests(b: *build.Builder, test_filter: ?[]const u8, modes: []const Mode) *build.Step {
-    const cases = b.allocator.create(BuildExamplesContext{
+    const cases = b.allocator.create(BuildExamplesContext) catch unreachable;
+    cases.* = BuildExamplesContext{
         .b = b,
         .step = b.step("test-build-examples", "Build the examples"),
         .test_index = 0,
         .test_filter = test_filter,
         .modes = modes,
-    }) catch unreachable;
+    };
 
     build_examples.addCases(cases);
 
@@ -119,13 +123,14 @@ pub fn addCliTests(b: *build.Builder, test_filter: ?[]const u8, modes: []const M
 }
 
 pub fn addAssembleAndLinkTests(b: *build.Builder, test_filter: ?[]const u8, modes: []const Mode) *build.Step {
-    const cases = b.allocator.create(CompareOutputContext{
+    const cases = b.allocator.create(CompareOutputContext) catch unreachable;
+    cases.* = CompareOutputContext{
         .b = b,
         .step = b.step("test-asm-link", "Run the assemble and link tests"),
         .test_index = 0,
         .test_filter = test_filter,
         .modes = modes,
-    }) catch unreachable;
+    };
 
     assemble_and_link.addCases(cases);
 
@@ -133,12 +138,13 @@ pub fn addAssembleAndLinkTests(b: *build.Builder, test_filter: ?[]const u8, mode
 }
 
 pub fn addTranslateCTests(b: *build.Builder, test_filter: ?[]const u8) *build.Step {
-    const cases = b.allocator.create(TranslateCContext{
+    const cases = b.allocator.create(TranslateCContext) catch unreachable;
+    cases.* = TranslateCContext{
         .b = b,
         .step = b.step("test-translate-c", "Run the C transation tests"),
         .test_index = 0,
         .test_filter = test_filter,
-    }) catch unreachable;
+    };
 
     translate_c.addCases(cases);
 
@@ -146,12 +152,13 @@ pub fn addTranslateCTests(b: *build.Builder, test_filter: ?[]const u8) *build.St
 }
 
 pub fn addGenHTests(b: *build.Builder, test_filter: ?[]const u8) *build.Step {
-    const cases = b.allocator.create(GenHContext{
+    const cases = b.allocator.create(GenHContext) catch unreachable;
+    cases.* = GenHContext{
         .b = b,
         .step = b.step("test-gen-h", "Run the C header file generation tests"),
         .test_index = 0,
         .test_filter = test_filter,
-    }) catch unreachable;
+    };
 
     gen_h.addCases(cases);
 
@@ -244,7 +251,8 @@ pub const CompareOutputContext = struct {
 
         pub fn create(context: *CompareOutputContext, exe_path: []const u8, name: []const u8, expected_output: []const u8, cli_args: []const []const u8) *RunCompareOutputStep {
             const allocator = context.b.allocator;
-            const ptr = allocator.create(RunCompareOutputStep{
+            const ptr = allocator.create(RunCompareOutputStep) catch unreachable;
+            ptr.* = RunCompareOutputStep{
                 .context = context,
                 .exe_path = exe_path,
                 .name = name,
@@ -252,7 +260,7 @@ pub const CompareOutputContext = struct {
                 .test_index = context.test_index,
                 .step = build.Step.init("RunCompareOutput", allocator, make),
                 .cli_args = cli_args,
-            }) catch unreachable;
+            };
             context.test_index += 1;
             return ptr;
         }
@@ -331,13 +339,14 @@ pub const CompareOutputContext = struct {
 
         pub fn create(context: *CompareOutputContext, exe_path: []const u8, name: []const u8) *RuntimeSafetyRunStep {
             const allocator = context.b.allocator;
-            const ptr = allocator.create(RuntimeSafetyRunStep{
+            const ptr = allocator.create(RuntimeSafetyRunStep) catch unreachable;
+            ptr.* = RuntimeSafetyRunStep{
                 .context = context,
                 .exe_path = exe_path,
                 .name = name,
                 .test_index = context.test_index,
                 .step = build.Step.init("RuntimeSafetyRun", allocator, make),
-            }) catch unreachable;
+            };
 
             context.test_index += 1;
             return ptr;
@@ -542,14 +551,15 @@ pub const CompileErrorContext = struct {
 
         pub fn create(context: *CompileErrorContext, name: []const u8, case: *const TestCase, build_mode: Mode) *CompileCmpOutputStep {
             const allocator = context.b.allocator;
-            const ptr = allocator.create(CompileCmpOutputStep{
+            const ptr = allocator.create(CompileCmpOutputStep) catch unreachable;
+            ptr.* = CompileCmpOutputStep{
                 .step = build.Step.init("CompileCmpOutput", allocator, make),
                 .context = context,
                 .name = name,
                 .test_index = context.test_index,
                 .case = case,
                 .build_mode = build_mode,
-            }) catch unreachable;
+            };
 
             context.test_index += 1;
             return ptr;
@@ -661,13 +671,14 @@ pub const CompileErrorContext = struct {
     }
 
     pub fn create(self: *CompileErrorContext, name: []const u8, source: []const u8, expected_lines: ...) *TestCase {
-        const tc = self.b.allocator.create(TestCase{
+        const tc = self.b.allocator.create(TestCase) catch unreachable;
+        tc.* = TestCase{
             .name = name,
             .sources = ArrayList(TestCase.SourceFile).init(self.b.allocator),
             .expected_errors = ArrayList([]const u8).init(self.b.allocator),
             .link_libc = false,
             .is_exe = false,
-        }) catch unreachable;
+        };
 
         tc.addSourceFile(".tmp_source.zig", source);
         comptime var arg_i = 0;
@@ -821,13 +832,14 @@ pub const TranslateCContext = struct {
 
         pub fn create(context: *TranslateCContext, name: []const u8, case: *const TestCase) *TranslateCCmpOutputStep {
             const allocator = context.b.allocator;
-            const ptr = allocator.create(TranslateCCmpOutputStep{
+            const ptr = allocator.create(TranslateCCmpOutputStep) catch unreachable;
+            ptr.* = TranslateCCmpOutputStep{
                 .step = build.Step.init("ParseCCmpOutput", allocator, make),
                 .context = context,
                 .name = name,
                 .test_index = context.test_index,
                 .case = case,
-            }) catch unreachable;
+            };
 
             context.test_index += 1;
             return ptr;
@@ -928,12 +940,13 @@ pub const TranslateCContext = struct {
     }
 
     pub fn create(self: *TranslateCContext, allow_warnings: bool, filename: []const u8, name: []const u8, source: []const u8, expected_lines: ...) *TestCase {
-        const tc = self.b.allocator.create(TestCase{
+        const tc = self.b.allocator.create(TestCase) catch unreachable;
+        tc.* = TestCase{
             .name = name,
             .sources = ArrayList(TestCase.SourceFile).init(self.b.allocator),
             .expected_lines = ArrayList([]const u8).init(self.b.allocator),
             .allow_warnings = allow_warnings,
-        }) catch unreachable;
+        };
 
         tc.addSourceFile(filename, source);
         comptime var arg_i = 0;
@@ -1015,14 +1028,15 @@ pub const GenHContext = struct {
 
         pub fn create(context: *GenHContext, h_path: []const u8, name: []const u8, case: *const TestCase) *GenHCmpOutputStep {
             const allocator = context.b.allocator;
-            const ptr = allocator.create(GenHCmpOutputStep{
+            const ptr = allocator.create(GenHCmpOutputStep) catch unreachable;
+            ptr.* = GenHCmpOutputStep{
                 .step = build.Step.init("ParseCCmpOutput", allocator, make),
                 .context = context,
                 .h_path = h_path,
                 .name = name,
                 .test_index = context.test_index,
                 .case = case,
-            }) catch unreachable;
+            };
 
             context.test_index += 1;
             return ptr;
@@ -1062,11 +1076,12 @@ pub const GenHContext = struct {
     }
 
     pub fn create(self: *GenHContext, filename: []const u8, name: []const u8, source: []const u8, expected_lines: ...) *TestCase {
-        const tc = self.b.allocator.create(TestCase{
+        const tc = self.b.allocator.create(TestCase) catch unreachable;
+        tc.* = TestCase{
             .name = name,
             .sources = ArrayList(TestCase.SourceFile).init(self.b.allocator),
             .expected_lines = ArrayList([]const u8).init(self.b.allocator),
-        }) catch unreachable;
+        };
 
         tc.addSourceFile(filename, source);
         comptime var arg_i = 0;