stage2: rework Value storage of structs and arrays

Now they both use `Value.Tag.aggregate`.

Additionally the LLVM backend now has implemented lowering of
tuple values.
This commit is contained in:
Andrew Kelley 2022-03-14 12:28:52 -07:00
parent 1ebe3bd01d
commit 5ea94e7715
9 changed files with 213 additions and 178 deletions

View File

@ -5385,7 +5385,7 @@ pub fn populateTestFunctions(mod: *Module) !void {
.len = test_fn_vals.len, .len = test_fn_vals.len,
.elem_type = try tmp_test_fn_ty.copy(arena), .elem_type = try tmp_test_fn_ty.copy(arena),
}), }),
.val = try Value.Tag.array.create(arena, test_fn_vals), .val = try Value.Tag.aggregate.create(arena, test_fn_vals),
}); });
// Add a dependency on each test name and function pointer. // Add a dependency on each test name and function pointer.
@ -5417,7 +5417,7 @@ pub fn populateTestFunctions(mod: *Module) !void {
try Value.Tag.decl_ref.create(arena, test_decl), // func try Value.Tag.decl_ref.create(arena, test_decl), // func
Value.initTag(.null_value), // async_frame_size Value.initTag(.null_value), // async_frame_size
}; };
test_fn_vals[i] = try Value.Tag.@"struct".create(arena, field_vals); test_fn_vals[i] = try Value.Tag.aggregate.create(arena, field_vals);
} }
try array_decl.finalizeNewArena(&new_decl_arena); try array_decl.finalizeNewArena(&new_decl_arena);

View File

@ -3119,7 +3119,7 @@ fn validateStructInit(
field_values[i] = fields[i].default_val; field_values[i] = fields[i].default_val;
} }
const struct_val = try Value.Tag.@"struct".create(sema.arena, field_values); const struct_val = try Value.Tag.aggregate.create(sema.arena, field_values);
const struct_init = try sema.addConstant(struct_ty, struct_val); const struct_init = try sema.addConstant(struct_ty, struct_val);
try sema.storePtr2(block, init_src, struct_ptr, init_src, struct_init, init_src, .store); try sema.storePtr2(block, init_src, struct_ptr, init_src, struct_init, init_src, .store);
return; return;
@ -3246,7 +3246,7 @@ fn zirValidateArrayInit(
block.instructions.shrinkRetainingCapacity(first_block_index); block.instructions.shrinkRetainingCapacity(first_block_index);
const array_val = try Value.Tag.array.create(sema.arena, element_vals); const array_val = try Value.Tag.aggregate.create(sema.arena, element_vals);
const array_init = try sema.addConstant(array_ty, array_val); const array_init = try sema.addConstant(array_ty, array_val);
try sema.storePtr2(block, init_src, array_ptr, init_src, array_init, init_src, .store); try sema.storePtr2(block, init_src, array_ptr, init_src, array_init, init_src, .store);
} }
@ -8175,7 +8175,7 @@ fn zirBitNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
} }
return sema.addConstant( return sema.addConstant(
operand_type, operand_type,
try Value.Tag.array.create(sema.arena, elems), try Value.Tag.aggregate.create(sema.arena, elems),
); );
} else { } else {
const result_val = try val.bitwiseNot(scalar_type, sema.arena, target); const result_val = try val.bitwiseNot(scalar_type, sema.arena, target);
@ -8239,7 +8239,7 @@ fn analyzeTupleCat(
}); });
const runtime_src = opt_runtime_src orelse { const runtime_src = opt_runtime_src orelse {
const tuple_val = try Value.Tag.@"struct".create(sema.arena, values); const tuple_val = try Value.Tag.aggregate.create(sema.arena, values);
return sema.addConstant(tuple_ty, tuple_val); return sema.addConstant(tuple_ty, tuple_val);
}; };
@ -8334,7 +8334,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
.len = final_len, .len = final_len,
.elem_type = try lhs_info.elem_type.copy(anon_decl.arena()), .elem_type = try lhs_info.elem_type.copy(anon_decl.arena()),
}); });
const val = try Value.Tag.array.create(anon_decl.arena(), buf); const val = try Value.Tag.aggregate.create(anon_decl.arena(), buf);
const decl = try anon_decl.finish(ty, val); const decl = try anon_decl.finish(ty, val);
if (lhs_single_ptr or rhs_single_ptr) { if (lhs_single_ptr or rhs_single_ptr) {
return sema.analyzeDeclRef(decl); return sema.analyzeDeclRef(decl);
@ -8419,7 +8419,7 @@ fn analyzeTupleMul(
}); });
const runtime_src = opt_runtime_src orelse { const runtime_src = opt_runtime_src orelse {
const tuple_val = try Value.Tag.@"struct".create(sema.arena, values); const tuple_val = try Value.Tag.aggregate.create(sema.arena, values);
return sema.addConstant(tuple_ty, tuple_val); return sema.addConstant(tuple_ty, tuple_val);
}; };
@ -8506,7 +8506,7 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
if (mulinfo.sentinel) |sent| { if (mulinfo.sentinel) |sent| {
buf[final_len] = try sent.copy(anon_decl.arena()); buf[final_len] = try sent.copy(anon_decl.arena());
} }
break :blk try Value.Tag.array.create(anon_decl.arena(), buf); break :blk try Value.Tag.aggregate.create(anon_decl.arena(), buf);
}; };
const decl = try anon_decl.finish(final_ty, val); const decl = try anon_decl.finish(final_ty, val);
if (is_single_ptr) { if (is_single_ptr) {
@ -10186,7 +10186,7 @@ fn zirBuiltinSrc(
return sema.addConstant( return sema.addConstant(
try sema.getBuiltinType(block, src, "SourceLocation"), try sema.getBuiltinType(block, src, "SourceLocation"),
try Value.Tag.@"struct".create(sema.arena, field_values), try Value.Tag.aggregate.create(sema.arena, field_values),
); );
} }
@ -10289,7 +10289,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
// arg_type: ?type, // arg_type: ?type,
param_ty_val, param_ty_val,
}; };
param_val.* = try Value.Tag.@"struct".create(params_anon_decl.arena(), param_fields); param_val.* = try Value.Tag.aggregate.create(params_anon_decl.arena(), param_fields);
} }
const args_val = v: { const args_val = v: {
@ -10314,7 +10314,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
.len = param_vals.len, .len = param_vals.len,
.elem_type = param_info_decl.ty, .elem_type = param_info_decl.ty,
}), }),
try Value.Tag.array.create( try Value.Tag.aggregate.create(
params_anon_decl.arena(), params_anon_decl.arena(),
param_vals, param_vals,
), ),
@ -10345,7 +10345,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
type_info_ty, type_info_ty,
try Value.Tag.@"union".create(sema.arena, .{ try Value.Tag.@"union".create(sema.arena, .{
.tag = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(std.builtin.TypeId.Fn)), .tag = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(std.builtin.TypeId.Fn)),
.val = try Value.Tag.@"struct".create(sema.arena, field_values), .val = try Value.Tag.aggregate.create(sema.arena, field_values),
}), }),
); );
}, },
@ -10364,7 +10364,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
type_info_ty, type_info_ty,
try Value.Tag.@"union".create(sema.arena, .{ try Value.Tag.@"union".create(sema.arena, .{
.tag = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(std.builtin.TypeId.Int)), .tag = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(std.builtin.TypeId.Int)),
.val = try Value.Tag.@"struct".create(sema.arena, field_values), .val = try Value.Tag.aggregate.create(sema.arena, field_values),
}), }),
); );
}, },
@ -10377,7 +10377,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
type_info_ty, type_info_ty,
try Value.Tag.@"union".create(sema.arena, .{ try Value.Tag.@"union".create(sema.arena, .{
.tag = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(std.builtin.TypeId.Float)), .tag = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(std.builtin.TypeId.Float)),
.val = try Value.Tag.@"struct".create(sema.arena, field_values), .val = try Value.Tag.aggregate.create(sema.arena, field_values),
}), }),
); );
}, },
@ -10412,7 +10412,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
type_info_ty, type_info_ty,
try Value.Tag.@"union".create(sema.arena, .{ try Value.Tag.@"union".create(sema.arena, .{
.tag = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(std.builtin.TypeId.Pointer)), .tag = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(std.builtin.TypeId.Pointer)),
.val = try Value.Tag.@"struct".create(sema.arena, field_values), .val = try Value.Tag.aggregate.create(sema.arena, field_values),
}), }),
); );
}, },
@ -10430,7 +10430,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
type_info_ty, type_info_ty,
try Value.Tag.@"union".create(sema.arena, .{ try Value.Tag.@"union".create(sema.arena, .{
.tag = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(std.builtin.TypeId.Array)), .tag = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(std.builtin.TypeId.Array)),
.val = try Value.Tag.@"struct".create(sema.arena, field_values), .val = try Value.Tag.aggregate.create(sema.arena, field_values),
}), }),
); );
}, },
@ -10446,7 +10446,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
type_info_ty, type_info_ty,
try Value.Tag.@"union".create(sema.arena, .{ try Value.Tag.@"union".create(sema.arena, .{
.tag = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(std.builtin.TypeId.Vector)), .tag = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(std.builtin.TypeId.Vector)),
.val = try Value.Tag.@"struct".create(sema.arena, field_values), .val = try Value.Tag.aggregate.create(sema.arena, field_values),
}), }),
); );
}, },
@ -10459,7 +10459,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
type_info_ty, type_info_ty,
try Value.Tag.@"union".create(sema.arena, .{ try Value.Tag.@"union".create(sema.arena, .{
.tag = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(std.builtin.TypeId.Optional)), .tag = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(std.builtin.TypeId.Optional)),
.val = try Value.Tag.@"struct".create(sema.arena, field_values), .val = try Value.Tag.aggregate.create(sema.arena, field_values),
}), }),
); );
}, },
@ -10509,7 +10509,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
name_val, name_val,
}; };
field_val.* = try Value.Tag.@"struct".create( field_val.* = try Value.Tag.aggregate.create(
fields_anon_decl.arena(), fields_anon_decl.arena(),
error_field_fields, error_field_fields,
); );
@ -10525,7 +10525,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
.len = vals.len, .len = vals.len,
.elem_type = error_field_ty, .elem_type = error_field_ty,
}), }),
try Value.Tag.array.create( try Value.Tag.aggregate.create(
fields_anon_decl.arena(), fields_anon_decl.arena(),
vals, vals,
), ),
@ -10559,7 +10559,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
type_info_ty, type_info_ty,
try Value.Tag.@"union".create(sema.arena, .{ try Value.Tag.@"union".create(sema.arena, .{
.tag = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(std.builtin.TypeId.ErrorUnion)), .tag = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(std.builtin.TypeId.ErrorUnion)),
.val = try Value.Tag.@"struct".create(sema.arena, field_values), .val = try Value.Tag.aggregate.create(sema.arena, field_values),
}), }),
); );
}, },
@ -10618,7 +10618,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
// value: comptime_int, // value: comptime_int,
int_val, int_val,
}; };
field_val.* = try Value.Tag.@"struct".create(fields_anon_decl.arena(), enum_field_fields); field_val.* = try Value.Tag.aggregate.create(fields_anon_decl.arena(), enum_field_fields);
} }
const fields_val = v: { const fields_val = v: {
@ -10627,7 +10627,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
.len = enum_field_vals.len, .len = enum_field_vals.len,
.elem_type = enum_field_ty, .elem_type = enum_field_ty,
}), }),
try Value.Tag.array.create( try Value.Tag.aggregate.create(
fields_anon_decl.arena(), fields_anon_decl.arena(),
enum_field_vals, enum_field_vals,
), ),
@ -10659,7 +10659,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
type_info_ty, type_info_ty,
try Value.Tag.@"union".create(sema.arena, .{ try Value.Tag.@"union".create(sema.arena, .{
.tag = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(std.builtin.TypeId.Enum)), .tag = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(std.builtin.TypeId.Enum)),
.val = try Value.Tag.@"struct".create(sema.arena, field_values), .val = try Value.Tag.aggregate.create(sema.arena, field_values),
}), }),
); );
}, },
@ -10717,7 +10717,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
// alignment: comptime_int, // alignment: comptime_int,
try Value.Tag.int_u64.create(fields_anon_decl.arena(), alignment), try Value.Tag.int_u64.create(fields_anon_decl.arena(), alignment),
}; };
field_val.* = try Value.Tag.@"struct".create(fields_anon_decl.arena(), union_field_fields); field_val.* = try Value.Tag.aggregate.create(fields_anon_decl.arena(), union_field_fields);
} }
const fields_val = v: { const fields_val = v: {
@ -10726,7 +10726,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
.len = union_field_vals.len, .len = union_field_vals.len,
.elem_type = union_field_ty, .elem_type = union_field_ty,
}), }),
try Value.Tag.array.create( try Value.Tag.aggregate.create(
fields_anon_decl.arena(), fields_anon_decl.arena(),
try fields_anon_decl.arena().dupe(Value, union_field_vals), try fields_anon_decl.arena().dupe(Value, union_field_vals),
), ),
@ -10761,7 +10761,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
type_info_ty, type_info_ty,
try Value.Tag.@"union".create(sema.arena, .{ try Value.Tag.@"union".create(sema.arena, .{
.tag = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(std.builtin.TypeId.Union)), .tag = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(std.builtin.TypeId.Union)),
.val = try Value.Tag.@"struct".create(sema.arena, field_values), .val = try Value.Tag.aggregate.create(sema.arena, field_values),
}), }),
); );
}, },
@ -10827,7 +10827,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
// alignment: comptime_int, // alignment: comptime_int,
try Value.Tag.int_u64.create(fields_anon_decl.arena(), alignment), try Value.Tag.int_u64.create(fields_anon_decl.arena(), alignment),
}; };
struct_field_val.* = try Value.Tag.@"struct".create(fields_anon_decl.arena(), struct_field_fields); struct_field_val.* = try Value.Tag.aggregate.create(fields_anon_decl.arena(), struct_field_fields);
} }
break :fv struct_field_vals; break :fv struct_field_vals;
} }
@ -10871,7 +10871,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
// alignment: comptime_int, // alignment: comptime_int,
try Value.Tag.int_u64.create(fields_anon_decl.arena(), alignment), try Value.Tag.int_u64.create(fields_anon_decl.arena(), alignment),
}; };
field_val.* = try Value.Tag.@"struct".create(fields_anon_decl.arena(), struct_field_fields); field_val.* = try Value.Tag.aggregate.create(fields_anon_decl.arena(), struct_field_fields);
} }
break :fv struct_field_vals; break :fv struct_field_vals;
}; };
@ -10882,7 +10882,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
.len = struct_field_vals.len, .len = struct_field_vals.len,
.elem_type = struct_field_ty, .elem_type = struct_field_ty,
}), }),
try Value.Tag.array.create( try Value.Tag.aggregate.create(
fields_anon_decl.arena(), fields_anon_decl.arena(),
try fields_anon_decl.arena().dupe(Value, struct_field_vals), try fields_anon_decl.arena().dupe(Value, struct_field_vals),
), ),
@ -10911,7 +10911,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
type_info_ty, type_info_ty,
try Value.Tag.@"union".create(sema.arena, .{ try Value.Tag.@"union".create(sema.arena, .{
.tag = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(std.builtin.TypeId.Struct)), .tag = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(std.builtin.TypeId.Struct)),
.val = try Value.Tag.@"struct".create(sema.arena, field_values), .val = try Value.Tag.aggregate.create(sema.arena, field_values),
}), }),
); );
}, },
@ -10931,7 +10931,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
type_info_ty, type_info_ty,
try Value.Tag.@"union".create(sema.arena, .{ try Value.Tag.@"union".create(sema.arena, .{
.tag = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(std.builtin.TypeId.Opaque)), .tag = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(std.builtin.TypeId.Opaque)),
.val = try Value.Tag.@"struct".create(sema.arena, field_values), .val = try Value.Tag.aggregate.create(sema.arena, field_values),
}), }),
); );
}, },
@ -10987,7 +10987,7 @@ fn typeInfoDecls(
//is_pub: bool, //is_pub: bool,
Value.makeBool(decl.is_pub), Value.makeBool(decl.is_pub),
}; };
decls_val.* = try Value.Tag.@"struct".create(decls_anon_decl.arena(), fields); decls_val.* = try Value.Tag.aggregate.create(decls_anon_decl.arena(), fields);
} }
const new_decl = try decls_anon_decl.finish( const new_decl = try decls_anon_decl.finish(
@ -10995,7 +10995,7 @@ fn typeInfoDecls(
.len = decls_vals.len, .len = decls_vals.len,
.elem_type = declaration_ty, .elem_type = declaration_ty,
}), }),
try Value.Tag.array.create( try Value.Tag.aggregate.create(
decls_anon_decl.arena(), decls_anon_decl.arena(),
try decls_anon_decl.arena().dupe(Value, decls_vals), try decls_anon_decl.arena().dupe(Value, decls_vals),
), ),
@ -11816,7 +11816,7 @@ fn finishStructInit(
for (field_inits) |field_init, i| { for (field_inits) |field_init, i| {
values[i] = (sema.resolveMaybeUndefVal(block, src, field_init) catch unreachable).?; values[i] = (sema.resolveMaybeUndefVal(block, src, field_init) catch unreachable).?;
} }
const struct_val = try Value.Tag.@"struct".create(sema.arena, values); const struct_val = try Value.Tag.aggregate.create(sema.arena, values);
return sema.addConstantMaybeRef(block, src, struct_ty, struct_val, is_ref); return sema.addConstantMaybeRef(block, src, struct_ty, struct_val, is_ref);
} }
@ -11877,7 +11877,7 @@ fn zirStructInitAnon(
}); });
const runtime_src = opt_runtime_src orelse { const runtime_src = opt_runtime_src orelse {
const tuple_val = try Value.Tag.@"struct".create(sema.arena, values); const tuple_val = try Value.Tag.aggregate.create(sema.arena, values);
return sema.addConstantMaybeRef(block, src, tuple_ty, tuple_val, is_ref); return sema.addConstantMaybeRef(block, src, tuple_ty, tuple_val, is_ref);
}; };
@ -11974,7 +11974,7 @@ fn zirArrayInit(
elem_vals[i] = (sema.resolveMaybeUndefVal(block, src, arg) catch unreachable).?; elem_vals[i] = (sema.resolveMaybeUndefVal(block, src, arg) catch unreachable).?;
} }
const array_val = try Value.Tag.array.create(sema.arena, elem_vals); const array_val = try Value.Tag.aggregate.create(sema.arena, elem_vals);
return sema.addConstantMaybeRef(block, src, array_ty, array_val, is_ref); return sema.addConstantMaybeRef(block, src, array_ty, array_val, is_ref);
}; };
@ -12043,7 +12043,7 @@ fn zirArrayInitAnon(
}); });
const runtime_src = opt_runtime_src orelse { const runtime_src = opt_runtime_src orelse {
const tuple_val = try Value.Tag.@"struct".create(sema.arena, values); const tuple_val = try Value.Tag.aggregate.create(sema.arena, values);
return sema.addConstantMaybeRef(block, src, tuple_ty, tuple_val, is_ref); return sema.addConstantMaybeRef(block, src, tuple_ty, tuple_val, is_ref);
}; };
@ -12250,7 +12250,7 @@ fn zirUnaryMath(
} }
return sema.addConstant( return sema.addConstant(
result_ty, result_ty,
try Value.Tag.array.create(sema.arena, elems), try Value.Tag.aggregate.create(sema.arena, elems),
); );
} }
@ -12350,7 +12350,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
.AnyFrame => return Air.Inst.Ref.anyframe_type, .AnyFrame => return Air.Inst.Ref.anyframe_type,
.EnumLiteral => return Air.Inst.Ref.enum_literal_type, .EnumLiteral => return Air.Inst.Ref.enum_literal_type,
.Int => { .Int => {
const struct_val = union_val.val.castTag(.@"struct").?.data; const struct_val = union_val.val.castTag(.aggregate).?.data;
// TODO use reflection instead of magic numbers here // TODO use reflection instead of magic numbers here
const signedness_val = struct_val[0]; const signedness_val = struct_val[0];
const bits_val = struct_val[1]; const bits_val = struct_val[1];
@ -12364,7 +12364,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
return sema.addType(ty); return sema.addType(ty);
}, },
.Vector => { .Vector => {
const struct_val = union_val.val.castTag(.@"struct").?.data; const struct_val = union_val.val.castTag(.aggregate).?.data;
// TODO use reflection instead of magic numbers here // TODO use reflection instead of magic numbers here
const len_val = struct_val[0]; const len_val = struct_val[0];
const child_val = struct_val[1]; const child_val = struct_val[1];
@ -12377,7 +12377,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
return sema.addType(ty); return sema.addType(ty);
}, },
.Float => { .Float => {
const struct_val = union_val.val.castTag(.@"struct").?.data; const struct_val = union_val.val.castTag(.aggregate).?.data;
// TODO use reflection instead of magic numbers here // TODO use reflection instead of magic numbers here
// bits: comptime_int, // bits: comptime_int,
const bits_val = struct_val[0]; const bits_val = struct_val[0];
@ -12394,7 +12394,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
return sema.addType(ty); return sema.addType(ty);
}, },
.Pointer => { .Pointer => {
const struct_val = union_val.val.castTag(.@"struct").?.data; const struct_val = union_val.val.castTag(.aggregate).?.data;
// TODO use reflection instead of magic numbers here // TODO use reflection instead of magic numbers here
const size_val = struct_val[0]; const size_val = struct_val[0];
const is_const_val = struct_val[1]; const is_const_val = struct_val[1];
@ -12436,7 +12436,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
return sema.addType(ty); return sema.addType(ty);
}, },
.Array => { .Array => {
const struct_val = union_val.val.castTag(.@"struct").?.data; const struct_val = union_val.val.castTag(.aggregate).?.data;
// TODO use reflection instead of magic numbers here // TODO use reflection instead of magic numbers here
// len: comptime_int, // len: comptime_int,
const len_val = struct_val[0]; const len_val = struct_val[0];
@ -12460,7 +12460,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
return sema.addType(ty); return sema.addType(ty);
}, },
.Optional => { .Optional => {
const struct_val = union_val.val.castTag(.@"struct").?.data; const struct_val = union_val.val.castTag(.aggregate).?.data;
// TODO use reflection instead of magic numbers here // TODO use reflection instead of magic numbers here
// child: type, // child: type,
const child_val = struct_val[0]; const child_val = struct_val[0];
@ -12472,7 +12472,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
return sema.addType(ty); return sema.addType(ty);
}, },
.ErrorUnion => { .ErrorUnion => {
const struct_val = union_val.val.castTag(.@"struct").?.data; const struct_val = union_val.val.castTag(.aggregate).?.data;
// TODO use reflection instead of magic numbers here // TODO use reflection instead of magic numbers here
// error_set: type, // error_set: type,
const error_set_val = struct_val[0]; const error_set_val = struct_val[0];
@ -12495,12 +12495,12 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
const slice_val = payload_val.castTag(.slice).?.data; const slice_val = payload_val.castTag(.slice).?.data;
const decl = slice_val.ptr.pointerDecl().?; const decl = slice_val.ptr.pointerDecl().?;
try sema.ensureDeclAnalyzed(decl); try sema.ensureDeclAnalyzed(decl);
const array_val = decl.val.castTag(.array).?.data; const array_val = decl.val.castTag(.aggregate).?.data;
var names: Module.ErrorSet.NameMap = .{}; var names: Module.ErrorSet.NameMap = .{};
try names.ensureUnusedCapacity(sema.arena, array_val.len); try names.ensureUnusedCapacity(sema.arena, array_val.len);
for (array_val) |elem_val| { for (array_val) |elem_val| {
const struct_val = elem_val.castTag(.@"struct").?.data; const struct_val = elem_val.castTag(.aggregate).?.data;
// TODO use reflection instead of magic numbers here // TODO use reflection instead of magic numbers here
// error_set: type, // error_set: type,
const name_val = struct_val[0]; const name_val = struct_val[0];
@ -12516,7 +12516,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
}, },
.Struct => { .Struct => {
// TODO use reflection instead of magic numbers here // TODO use reflection instead of magic numbers here
const struct_val = union_val.val.castTag(.@"struct").?.data; const struct_val = union_val.val.castTag(.aggregate).?.data;
// layout: containerlayout, // layout: containerlayout,
const layout_val = struct_val[0]; const layout_val = struct_val[0];
// fields: []const enumfield, // fields: []const enumfield,
@ -12537,7 +12537,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
try sema.reifyStruct(block, inst, src, layout_val, fields_val); try sema.reifyStruct(block, inst, src, layout_val, fields_val);
}, },
.Enum => { .Enum => {
const struct_val = union_val.val.castTag(.@"struct").?.data; const struct_val = union_val.val.castTag(.aggregate).?.data;
// TODO use reflection instead of magic numbers here // TODO use reflection instead of magic numbers here
// layout: ContainerLayout, // layout: ContainerLayout,
const layout_val = struct_val[0]; const layout_val = struct_val[0];
@ -12617,9 +12617,9 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
.ty = enum_obj.tag_ty, .ty = enum_obj.tag_ty,
}); });
const array_vals = decl.val.castTag(.array).?.data; const array_vals = decl.val.castTag(.aggregate).?.data;
for (array_vals) |elem_val| { for (array_vals) |elem_val| {
const field_struct_val = elem_val.castTag(.@"struct").?.data; const field_struct_val = elem_val.castTag(.aggregate).?.data;
// TODO use reflection instead of magic numbers here // TODO use reflection instead of magic numbers here
// name: []const u8 // name: []const u8
const name_val = field_struct_val[0]; const name_val = field_struct_val[0];
@ -12648,7 +12648,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
return sema.analyzeDeclVal(block, src, new_decl); return sema.analyzeDeclVal(block, src, new_decl);
}, },
.Opaque => { .Opaque => {
const struct_val = union_val.val.castTag(.@"struct").?.data; const struct_val = union_val.val.castTag(.aggregate).?.data;
// decls: []const Declaration, // decls: []const Declaration,
const decls_val = struct_val[0]; const decls_val = struct_val[0];
@ -12694,7 +12694,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
.Union => return sema.fail(block, src, "TODO: Sema.zirReify for Union", .{}), .Union => return sema.fail(block, src, "TODO: Sema.zirReify for Union", .{}),
.Fn => return sema.fail(block, src, "TODO: Sema.zirReify for Fn", .{}), .Fn => return sema.fail(block, src, "TODO: Sema.zirReify for Fn", .{}),
.BoundFn => @panic("TODO delete BoundFn from the language"), .BoundFn => @panic("TODO delete BoundFn from the language"),
.Frame => return sema.fail(block, src, "TODO: Sema.zirReify for Frame", .{}), .Frame => @panic("TODO implement https://github.com/ziglang/zig/issues/10710"),
} }
} }
@ -12717,7 +12717,7 @@ fn reifyTuple(
var i: usize = 0; var i: usize = 0;
while (i < fields_len) : (i += 1) { while (i < fields_len) : (i += 1) {
const elem_val = try fields_val.elemValue(sema.arena, i); const elem_val = try fields_val.elemValue(sema.arena, i);
const field_struct_val = elem_val.castTag(.@"struct").?.data; const field_struct_val = elem_val.castTag(.aggregate).?.data;
// TODO use reflection instead of magic numbers here // TODO use reflection instead of magic numbers here
// name: []const u8 // name: []const u8
const name_val = field_struct_val[0]; const name_val = field_struct_val[0];
@ -12818,7 +12818,7 @@ fn reifyStruct(
var i: usize = 0; var i: usize = 0;
while (i < fields_len) : (i += 1) { while (i < fields_len) : (i += 1) {
const elem_val = try fields_val.elemValue(sema.arena, i); const elem_val = try fields_val.elemValue(sema.arena, i);
const field_struct_val = elem_val.castTag(.@"struct").?.data; const field_struct_val = elem_val.castTag(.aggregate).?.data;
// TODO use reflection instead of magic numbers here // TODO use reflection instead of magic numbers here
// name: []const u8 // name: []const u8
const name_val = field_struct_val[0]; const name_val = field_struct_val[0];
@ -13219,7 +13219,7 @@ fn zirBitCount(
} }
return sema.addConstant( return sema.addConstant(
result_ty, result_ty,
try Value.Tag.array.create(sema.arena, elems), try Value.Tag.aggregate.create(sema.arena, elems),
); );
} else { } else {
try sema.requireRuntimeBlock(block, operand_src); try sema.requireRuntimeBlock(block, operand_src);
@ -13985,7 +13985,7 @@ fn analyzeShuffle(
values[i] = try b_val.elemValue(sema.arena, unsigned); values[i] = try b_val.elemValue(sema.arena, unsigned);
} }
} }
const res_val = try Value.Tag.array.create(sema.arena, values); const res_val = try Value.Tag.aggregate.create(sema.arena, values);
return sema.addConstant(res_ty, res_val); return sema.addConstant(res_ty, res_val);
} }
} }
@ -14008,7 +14008,7 @@ fn analyzeShuffle(
while (i < max_len) : (i += 1) { while (i < max_len) : (i += 1) {
expand_mask_values[i] = Value.negative_one; expand_mask_values[i] = Value.negative_one;
} }
const expand_mask = try Value.Tag.array.create(sema.arena, expand_mask_values); const expand_mask = try Value.Tag.aggregate.create(sema.arena, expand_mask_values);
if (a_len < b_len) { if (a_len < b_len) {
const undef = try sema.addConstUndef(a_ty); const undef = try sema.addConstUndef(a_ty);
@ -14454,7 +14454,7 @@ fn zirMinMax(
} }
return sema.addConstant( return sema.addConstant(
simd_op.result_ty, simd_op.result_ty,
try Value.Tag.array.create(sema.arena, elems), try Value.Tag.aggregate.create(sema.arena, elems),
); );
} else rs: { } else rs: {
if (simd_op.rhs_val) |rhs_val| { if (simd_op.rhs_val) |rhs_val| {
@ -16016,7 +16016,7 @@ fn structFieldVal(
return sema.addConstant(field.ty, opv); return sema.addConstant(field.ty, opv);
} }
const field_values = struct_val.castTag(.@"struct").?.data; const field_values = struct_val.castTag(.aggregate).?.data;
return sema.addConstant(field.ty, field_values[field_index]); return sema.addConstant(field.ty, field_values[field_index]);
} }
@ -16084,7 +16084,7 @@ fn tupleFieldValByIndex(
if ((try sema.typeHasOnePossibleValue(block, src, field_ty))) |opv| { if ((try sema.typeHasOnePossibleValue(block, src, field_ty))) |opv| {
return sema.addConstant(field_ty, opv); return sema.addConstant(field_ty, opv);
} }
const field_values = tuple_val.castTag(.@"struct").?.data; const field_values = tuple_val.castTag(.aggregate).?.data;
return sema.addConstant(field_ty, field_values[field_index]); return sema.addConstant(field_ty, field_values[field_index]);
} }
@ -16414,7 +16414,7 @@ fn tupleField(
if (try sema.resolveMaybeUndefVal(block, tuple_src, tuple)) |tuple_val| { if (try sema.resolveMaybeUndefVal(block, tuple_src, tuple)) |tuple_val| {
if (tuple_val.isUndef()) return sema.addConstUndef(field_ty); if (tuple_val.isUndef()) return sema.addConstUndef(field_ty);
const field_values = tuple_val.castTag(.@"struct").?.data; const field_values = tuple_val.castTag(.aggregate).?.data;
return sema.addConstant(field_ty, field_values[field_index]); return sema.addConstant(field_ty, field_values[field_index]);
} }
@ -17510,7 +17510,7 @@ fn beginComptimePtrMutation(
const elems = try arena.alloc(Value, array_len_including_sentinel); const elems = try arena.alloc(Value, array_len_including_sentinel);
mem.set(Value, elems, Value.undef); mem.set(Value, elems, Value.undef);
parent.val.* = try Value.Tag.array.create(arena, elems); parent.val.* = try Value.Tag.aggregate.create(arena, elems);
return ComptimePtrMutationKit{ return ComptimePtrMutationKit{
.decl_ref_mut = parent.decl_ref_mut, .decl_ref_mut = parent.decl_ref_mut,
@ -17537,7 +17537,7 @@ fn beginComptimePtrMutation(
elem.* = try Value.Tag.int_u64.create(arena, bytes[i]); elem.* = try Value.Tag.int_u64.create(arena, bytes[i]);
} }
parent.val.* = try Value.Tag.array.create(arena, elems); parent.val.* = try Value.Tag.aggregate.create(arena, elems);
return ComptimePtrMutationKit{ return ComptimePtrMutationKit{
.decl_ref_mut = parent.decl_ref_mut, .decl_ref_mut = parent.decl_ref_mut,
@ -17562,7 +17562,7 @@ fn beginComptimePtrMutation(
const elems = try arena.alloc(Value, array_len_including_sentinel); const elems = try arena.alloc(Value, array_len_including_sentinel);
mem.set(Value, elems, repeated_val); mem.set(Value, elems, repeated_val);
parent.val.* = try Value.Tag.array.create(arena, elems); parent.val.* = try Value.Tag.aggregate.create(arena, elems);
return ComptimePtrMutationKit{ return ComptimePtrMutationKit{
.decl_ref_mut = parent.decl_ref_mut, .decl_ref_mut = parent.decl_ref_mut,
@ -17571,9 +17571,9 @@ fn beginComptimePtrMutation(
}; };
}, },
.array => return ComptimePtrMutationKit{ .aggregate => return ComptimePtrMutationKit{
.decl_ref_mut = parent.decl_ref_mut, .decl_ref_mut = parent.decl_ref_mut,
.val = &parent.val.castTag(.array).?.data[elem_ptr.index], .val = &parent.val.castTag(.aggregate).?.data[elem_ptr.index],
.ty = elem_ty, .ty = elem_ty,
}, },
@ -17613,7 +17613,7 @@ fn beginComptimePtrMutation(
const fields = try arena.alloc(Value, parent.ty.structFieldCount()); const fields = try arena.alloc(Value, parent.ty.structFieldCount());
mem.set(Value, fields, Value.undef); mem.set(Value, fields, Value.undef);
parent.val.* = try Value.Tag.@"struct".create(arena, fields); parent.val.* = try Value.Tag.aggregate.create(arena, fields);
return ComptimePtrMutationKit{ return ComptimePtrMutationKit{
.decl_ref_mut = parent.decl_ref_mut, .decl_ref_mut = parent.decl_ref_mut,
@ -17639,9 +17639,9 @@ fn beginComptimePtrMutation(
else => unreachable, else => unreachable,
} }
}, },
.@"struct" => return ComptimePtrMutationKit{ .aggregate => return ComptimePtrMutationKit{
.decl_ref_mut = parent.decl_ref_mut, .decl_ref_mut = parent.decl_ref_mut,
.val = &parent.val.castTag(.@"struct").?.data[field_index], .val = &parent.val.castTag(.aggregate).?.data[field_index],
.ty = field_ty, .ty = field_ty,
}, },
.@"union" => { .@"union" => {
@ -18209,7 +18209,7 @@ fn coerceArrayLike(
return sema.addConstant( return sema.addConstant(
dest_ty, dest_ty,
try Value.Tag.array.create(sema.arena, element_vals), try Value.Tag.aggregate.create(sema.arena, element_vals),
); );
} }
@ -18266,7 +18266,7 @@ fn coerceTupleToArray(
return sema.addConstant( return sema.addConstant(
dest_ty, dest_ty,
try Value.Tag.array.create(sema.arena, element_vals), try Value.Tag.aggregate.create(sema.arena, element_vals),
); );
} }
@ -18397,7 +18397,7 @@ fn coerceTupleToStruct(
return sema.addConstant( return sema.addConstant(
struct_ty, struct_ty,
try Value.Tag.@"struct".create(sema.arena, field_vals), try Value.Tag.aggregate.create(sema.arena, field_vals),
); );
} }

View File

@ -225,9 +225,9 @@ pub fn generateSymbol(
return Result{ .externally_managed = payload.data }; return Result{ .externally_managed = payload.data };
} }
}, },
.array => { .aggregate => {
// TODO populate .debug_info for the array // TODO populate .debug_info for the array
const elem_vals = typed_value.val.castTag(.array).?.data; const elem_vals = typed_value.val.castTag(.aggregate).?.data;
const elem_ty = typed_value.ty.elemType(); const elem_ty = typed_value.ty.elemType();
for (elem_vals) |elem_val| { for (elem_vals) |elem_val| {
switch (try generateSymbol(bin_file, src_loc, .{ switch (try generateSymbol(bin_file, src_loc, .{
@ -554,7 +554,7 @@ pub fn generateSymbol(
} }
const struct_begin = code.items.len; const struct_begin = code.items.len;
const field_vals = typed_value.val.castTag(.@"struct").?.data; const field_vals = typed_value.val.castTag(.aggregate).?.data;
for (field_vals) |field_val, index| { for (field_vals) |field_val, index| {
const field_ty = typed_value.ty.structFieldType(index); const field_ty = typed_value.ty.structFieldType(index);
if (!field_ty.hasRuntimeBits()) continue; if (!field_ty.hasRuntimeBits()) continue;

View File

@ -748,7 +748,7 @@ pub const DeclGen = struct {
else => unreachable, else => unreachable,
}, },
.Struct => { .Struct => {
const field_vals = val.castTag(.@"struct").?.data; const field_vals = val.castTag(.aggregate).?.data;
try writer.writeAll("("); try writer.writeAll("(");
try dg.renderTypecast(writer, ty); try dg.renderTypecast(writer, ty);

View File

@ -1511,8 +1511,8 @@ pub const DeclGen = struct {
.True, // don't null terminate. bytes has the sentinel, if any. .True, // don't null terminate. bytes has the sentinel, if any.
); );
}, },
.array => { .aggregate => {
const elem_vals = tv.val.castTag(.array).?.data; const elem_vals = tv.val.castTag(.aggregate).?.data;
const elem_ty = tv.ty.elemType(); const elem_ty = tv.ty.elemType();
const gpa = dg.gpa; const gpa = dg.gpa;
const llvm_elems = try gpa.alloc(*const llvm.Value, elem_vals.len); const llvm_elems = try gpa.alloc(*const llvm.Value, elem_vals.len);
@ -1665,11 +1665,76 @@ pub const DeclGen = struct {
}, },
.Struct => { .Struct => {
const llvm_struct_ty = try dg.llvmType(tv.ty); const llvm_struct_ty = try dg.llvmType(tv.ty);
const field_vals = tv.val.castTag(.@"struct").?.data; const field_vals = tv.val.castTag(.aggregate).?.data;
const gpa = dg.gpa; const gpa = dg.gpa;
const struct_obj = tv.ty.castTag(.@"struct").?.data;
const target = dg.module.getTarget(); const target = dg.module.getTarget();
if (tv.ty.isTupleOrAnonStruct()) {
const tuple = tv.ty.tupleFields();
var llvm_fields: std.ArrayListUnmanaged(*const llvm.Value) = .{};
defer llvm_fields.deinit(gpa);
try llvm_fields.ensureUnusedCapacity(gpa, tuple.types.len);
comptime assert(struct_layout_version == 2);
var offset: u64 = 0;
var big_align: u32 = 0;
var need_unnamed = false;
for (tuple.types) |field_ty, i| {
if (tuple.values[i].tag() != .unreachable_value) continue;
if (!field_ty.hasRuntimeBitsIgnoreComptime()) continue;
const field_align = field_ty.abiAlignment(target);
big_align = @maximum(big_align, field_align);
const prev_offset = offset;
offset = std.mem.alignForwardGeneric(u64, offset, field_align);
const padding_len = offset - prev_offset;
if (padding_len > 0) {
const llvm_array_ty = dg.context.intType(8).arrayType(@intCast(c_uint, padding_len));
// TODO make this and all other padding elsewhere in debug
// builds be 0xaa not undef.
llvm_fields.appendAssumeCapacity(llvm_array_ty.getUndef());
}
const field_llvm_val = try dg.genTypedValue(.{
.ty = field_ty,
.val = field_vals[i],
});
need_unnamed = need_unnamed or dg.isUnnamedType(field_ty, field_llvm_val);
llvm_fields.appendAssumeCapacity(field_llvm_val);
offset += field_ty.abiSize(target);
}
{
const prev_offset = offset;
offset = std.mem.alignForwardGeneric(u64, offset, big_align);
const padding_len = offset - prev_offset;
if (padding_len > 0) {
const llvm_array_ty = dg.context.intType(8).arrayType(@intCast(c_uint, padding_len));
llvm_fields.appendAssumeCapacity(llvm_array_ty.getUndef());
}
}
if (need_unnamed) {
return dg.context.constStruct(
llvm_fields.items.ptr,
@intCast(c_uint, llvm_fields.items.len),
.False,
);
} else {
return llvm_struct_ty.constNamedStruct(
llvm_fields.items.ptr,
@intCast(c_uint, llvm_fields.items.len),
);
}
}
const struct_obj = tv.ty.castTag(.@"struct").?.data;
if (struct_obj.layout == .Packed) { if (struct_obj.layout == .Packed) {
const big_bits = struct_obj.packedIntegerBits(target); const big_bits = struct_obj.packedIntegerBits(target);
const int_llvm_ty = dg.context.intType(big_bits); const int_llvm_ty = dg.context.intType(big_bits);
@ -1707,8 +1772,8 @@ pub const DeclGen = struct {
comptime assert(struct_layout_version == 2); comptime assert(struct_layout_version == 2);
var offset: u64 = 0; var offset: u64 = 0;
var big_align: u32 = 0; var big_align: u32 = 0;
var need_unnamed = false; var need_unnamed = false;
for (struct_obj.fields.values()) |field, i| { for (struct_obj.fields.values()) |field, i| {
if (field.is_comptime or !field.ty.hasRuntimeBitsIgnoreComptime()) continue; if (field.is_comptime or !field.ty.hasRuntimeBitsIgnoreComptime()) continue;
@ -1854,10 +1919,10 @@ pub const DeclGen = struct {
@intCast(c_uint, llvm_elems.len), @intCast(c_uint, llvm_elems.len),
); );
}, },
.array => { .aggregate => {
// Note, sentinel is not stored even if the type has a sentinel. // Note, sentinel is not stored even if the type has a sentinel.
// The value includes the sentinel in those cases. // The value includes the sentinel in those cases.
const elem_vals = tv.val.castTag(.array).?.data; const elem_vals = tv.val.castTag(.aggregate).?.data;
const vector_len = @intCast(usize, tv.ty.arrayLen()); const vector_len = @intCast(usize, tv.ty.arrayLen());
assert(vector_len == elem_vals.len or vector_len + 1 == elem_vals.len); assert(vector_len == elem_vals.len or vector_len + 1 == elem_vals.len);
const elem_ty = tv.ty.elemType(); const elem_ty = tv.ty.elemType();

View File

@ -3877,7 +3877,7 @@ fn needsPointerRebase(ty: Type, val: Value) bool {
.Struct => { .Struct => {
const fields = ty.structFields().values(); const fields = ty.structFields().values();
if (fields.len == 0) return false; if (fields.len == 0) return false;
if (val.castTag(.@"struct")) |payload| { if (val.castTag(.aggregate)) |payload| {
const field_values = payload.data; const field_values = payload.data;
for (field_values) |field_val, i| { for (field_values) |field_val, i| {
if (needsPointerRebase(fields[i].ty, field_val)) return true; if (needsPointerRebase(fields[i].ty, field_val)) return true;

View File

@ -3568,6 +3568,8 @@ pub const Type = extern union {
.const_slice_u8, .const_slice_u8,
.const_slice, .const_slice,
.mut_slice, .mut_slice,
.tuple,
.empty_struct_literal,
=> return null, => return null,
.pointer => return self.castTag(.pointer).?.data.sentinel, .pointer => return self.castTag(.pointer).?.data.sentinel,

View File

@ -127,10 +127,6 @@ pub const Value = extern union {
/// This value is repeated some number of times. The amount of times to repeat /// This value is repeated some number of times. The amount of times to repeat
/// is stored externally. /// is stored externally.
repeated, repeated,
/// Each element stored as a `Value`.
/// In the case of sentinel-terminated arrays, the sentinel value *is* stored,
/// so the slice length will be one more than the type's array length.
array,
/// An array with length 0 but it has a sentinel. /// An array with length 0 but it has a sentinel.
empty_array_sentinel, empty_array_sentinel,
/// Pointer and length as sub `Value` objects. /// Pointer and length as sub `Value` objects.
@ -162,8 +158,11 @@ pub const Value = extern union {
opt_payload, opt_payload,
/// A pointer to the payload of an optional, based on a pointer to an optional. /// A pointer to the payload of an optional, based on a pointer to an optional.
opt_payload_ptr, opt_payload_ptr,
/// An instance of a struct. /// An instance of a struct, array, or vector.
@"struct", /// Each element/field stored as a `Value`.
/// In the case of sentinel-terminated arrays, the sentinel value *is* stored,
/// so the slice length will be one more than the type's array length.
aggregate,
/// An instance of a union. /// An instance of a union.
@"union", @"union",
/// This is a special value that tracks a set of types that have been stored /// This is a special value that tracks a set of types that have been stored
@ -279,7 +278,6 @@ pub const Value = extern union {
.enum_literal, .enum_literal,
=> Payload.Bytes, => Payload.Bytes,
.array => Payload.Array,
.slice => Payload.Slice, .slice => Payload.Slice,
.enum_field_index => Payload.U32, .enum_field_index => Payload.U32,
@ -301,7 +299,7 @@ pub const Value = extern union {
.@"error" => Payload.Error, .@"error" => Payload.Error,
.inferred_alloc => Payload.InferredAlloc, .inferred_alloc => Payload.InferredAlloc,
.inferred_alloc_comptime => Payload.InferredAllocComptime, .inferred_alloc_comptime => Payload.InferredAllocComptime,
.@"struct" => Payload.Struct, .aggregate => Payload.Aggregate,
.@"union" => Payload.Union, .@"union" => Payload.Union,
.bound_fn => Payload.BoundFn, .bound_fn => Payload.BoundFn,
}; };
@ -521,18 +519,6 @@ pub const Value = extern union {
}; };
return Value{ .ptr_otherwise = &new_payload.base }; return Value{ .ptr_otherwise = &new_payload.base };
}, },
.array => {
const payload = self.castTag(.array).?;
const new_payload = try arena.create(Payload.Array);
new_payload.* = .{
.base = payload.base,
.data = try arena.alloc(Value, payload.data.len),
};
for (new_payload.data) |*elem, i| {
elem.* = try payload.data[i].copy(arena);
}
return Value{ .ptr_otherwise = &new_payload.base };
},
.slice => { .slice => {
const payload = self.castTag(.slice).?; const payload = self.castTag(.slice).?;
const new_payload = try arena.create(Payload.Slice); const new_payload = try arena.create(Payload.Slice);
@ -562,15 +548,15 @@ pub const Value = extern union {
.enum_field_index => return self.copyPayloadShallow(arena, Payload.U32), .enum_field_index => return self.copyPayloadShallow(arena, Payload.U32),
.@"error" => return self.copyPayloadShallow(arena, Payload.Error), .@"error" => return self.copyPayloadShallow(arena, Payload.Error),
.@"struct" => { .aggregate => {
const old_field_values = self.castTag(.@"struct").?.data; const payload = self.castTag(.aggregate).?;
const new_payload = try arena.create(Payload.Struct); const new_payload = try arena.create(Payload.Aggregate);
new_payload.* = .{ new_payload.* = .{
.base = .{ .tag = .@"struct" }, .base = payload.base,
.data = try arena.alloc(Value, old_field_values.len), .data = try arena.alloc(Value, payload.data.len),
}; };
for (old_field_values) |old_field_val, i| { for (new_payload.data) |*elem, i| {
new_payload.data[i] = try old_field_val.copy(arena); elem.* = try payload.data[i].copy(arena);
} }
return Value{ .ptr_otherwise = &new_payload.base }; return Value{ .ptr_otherwise = &new_payload.base };
}, },
@ -677,8 +663,8 @@ pub const Value = extern union {
.abi_align_default => return out_stream.writeAll("(default ABI alignment)"), .abi_align_default => return out_stream.writeAll("(default ABI alignment)"),
.empty_struct_value => return out_stream.writeAll("struct {}{}"), .empty_struct_value => return out_stream.writeAll("struct {}{}"),
.@"struct" => { .aggregate => {
return out_stream.writeAll("(struct value)"); return out_stream.writeAll("(aggregate)");
}, },
.@"union" => { .@"union" => {
return out_stream.writeAll("(union value)"); return out_stream.writeAll("(union value)");
@ -733,7 +719,6 @@ pub const Value = extern union {
try out_stream.writeAll("(repeated) "); try out_stream.writeAll("(repeated) ");
val = val.castTag(.repeated).?.data; val = val.castTag(.repeated).?.data;
}, },
.array => return out_stream.writeAll("(array)"),
.empty_array_sentinel => return out_stream.writeAll("(empty array with sentinel)"), .empty_array_sentinel => return out_stream.writeAll("(empty array with sentinel)"),
.slice => return out_stream.writeAll("(slice)"), .slice => return out_stream.writeAll("(slice)"),
.float_16 => return out_stream.print("{}", .{val.castTag(.float_16).?.data}), .float_16 => return out_stream.print("{}", .{val.castTag(.float_16).?.data}),
@ -1087,7 +1072,7 @@ pub const Value = extern union {
.Auto => unreachable, // Sema is supposed to have emitted a compile error already .Auto => unreachable, // Sema is supposed to have emitted a compile error already
.Extern => { .Extern => {
const fields = ty.structFields().values(); const fields = ty.structFields().values();
const field_vals = val.castTag(.@"struct").?.data; const field_vals = val.castTag(.aggregate).?.data;
for (fields) |field, i| { for (fields) |field, i| {
const off = @intCast(usize, ty.structFieldOffset(i, target)); const off = @intCast(usize, ty.structFieldOffset(i, target));
writeToMemory(field_vals[i], field.ty, target, buffer[off..]); writeToMemory(field_vals[i], field.ty, target, buffer[off..]);
@ -1110,7 +1095,7 @@ pub const Value = extern union {
fn packedStructToInt(val: Value, ty: Type, target: Target, buf: []std.math.big.Limb) BigIntConst { fn packedStructToInt(val: Value, ty: Type, target: Target, buf: []std.math.big.Limb) BigIntConst {
var bigint = BigIntMutable.init(buf, 0); var bigint = BigIntMutable.init(buf, 0);
const fields = ty.structFields().values(); const fields = ty.structFields().values();
const field_vals = val.castTag(.@"struct").?.data; const field_vals = val.castTag(.aggregate).?.data;
var bits: u16 = 0; var bits: u16 = 0;
// TODO allocate enough heap space instead of using this buffer // TODO allocate enough heap space instead of using this buffer
// on the stack. // on the stack.
@ -1185,7 +1170,7 @@ pub const Value = extern union {
elem.* = try readFromMemory(elem_ty, target, buffer[offset..], arena); elem.* = try readFromMemory(elem_ty, target, buffer[offset..], arena);
offset += @intCast(usize, elem_size); offset += @intCast(usize, elem_size);
} }
return Tag.array.create(arena, elems); return Tag.aggregate.create(arena, elems);
}, },
.Struct => switch (ty.containerLayout()) { .Struct => switch (ty.containerLayout()) {
.Auto => unreachable, // Sema is supposed to have emitted a compile error already .Auto => unreachable, // Sema is supposed to have emitted a compile error already
@ -1196,7 +1181,7 @@ pub const Value = extern union {
const off = @intCast(usize, ty.structFieldOffset(i, target)); const off = @intCast(usize, ty.structFieldOffset(i, target));
field_vals[i] = try readFromMemory(field.ty, target, buffer[off..], arena); field_vals[i] = try readFromMemory(field.ty, target, buffer[off..], arena);
} }
return Tag.@"struct".create(arena, field_vals); return Tag.aggregate.create(arena, field_vals);
}, },
.Packed => { .Packed => {
const endian = target.cpu.arch.endian(); const endian = target.cpu.arch.endian();
@ -1250,7 +1235,7 @@ pub const Value = extern union {
else => unreachable, else => unreachable,
}; };
} }
return Tag.@"struct".create(arena, field_vals); return Tag.aggregate.create(arena, field_vals);
} }
fn bitCastBigIntToFloat( fn bitCastBigIntToFloat(
@ -1827,9 +1812,9 @@ pub const Value = extern union {
assert(op == .eq); assert(op == .eq);
return lhs.castTag(.repeated).?.data.compareWithZero(.eq); return lhs.castTag(.repeated).?.data.compareWithZero(.eq);
}, },
.array => { .aggregate => {
assert(op == .eq); assert(op == .eq);
for (lhs.cast(Payload.Array).?.data) |elem_val| { for (lhs.castTag(.aggregate).?.data) |elem_val| {
if (!elem_val.compareWithZero(.eq)) return false; if (!elem_val.compareWithZero(.eq)) return false;
} }
return true; return true;
@ -1898,29 +1883,16 @@ pub const Value = extern union {
}, },
.eu_payload_ptr => @panic("TODO: Implement more pointer eql cases"), .eu_payload_ptr => @panic("TODO: Implement more pointer eql cases"),
.opt_payload_ptr => @panic("TODO: Implement more pointer eql cases"), .opt_payload_ptr => @panic("TODO: Implement more pointer eql cases"),
.array => {
const a_array = a.castTag(.array).?.data;
const b_array = b.castTag(.array).?.data;
if (a_array.len != b_array.len) return false;
const elem_ty = ty.childType();
for (a_array) |a_elem, i| {
const b_elem = b_array[i];
if (!eql(a_elem, b_elem, elem_ty)) return false;
}
return true;
},
.function => { .function => {
const a_payload = a.castTag(.function).?.data; const a_payload = a.castTag(.function).?.data;
const b_payload = b.castTag(.function).?.data; const b_payload = b.castTag(.function).?.data;
return a_payload == b_payload; return a_payload == b_payload;
}, },
.@"struct" => { .aggregate => {
const a_field_vals = a.castTag(.@"struct").?.data; const a_field_vals = a.castTag(.aggregate).?.data;
const b_field_vals = b.castTag(.@"struct").?.data; const b_field_vals = b.castTag(.aggregate).?.data;
assert(a_field_vals.len == b_field_vals.len); assert(a_field_vals.len == b_field_vals.len);
if (ty.isTupleOrAnonStruct()) { if (ty.isTupleOrAnonStruct()) {
const types = ty.tupleFields().types; const types = ty.tupleFields().types;
assert(types.len == a_field_vals.len); assert(types.len == a_field_vals.len);
@ -1929,10 +1901,21 @@ pub const Value = extern union {
} }
return true; return true;
} }
const fields = ty.structFields().values();
assert(fields.len == a_field_vals.len); if (ty.zigTypeTag() == .Struct) {
for (fields) |field, i| { const fields = ty.structFields().values();
if (!eql(a_field_vals[i], b_field_vals[i], field.ty)) return false; assert(fields.len == a_field_vals.len);
for (fields) |field, i| {
if (!eql(a_field_vals[i], b_field_vals[i], field.ty)) return false;
}
return true;
}
const elem_ty = ty.childType();
for (a_field_vals) |a_elem, i| {
const b_elem = b_field_vals[i];
if (!eql(a_elem, b_elem, elem_ty)) return false;
} }
return true; return true;
}, },
@ -2002,7 +1985,7 @@ pub const Value = extern union {
}, },
.Struct => { .Struct => {
// A tuple can be represented with .empty_struct_value, // A tuple can be represented with .empty_struct_value,
// the_one_possible_value, .@"struct" in which case we could // the_one_possible_value, .aggregate in which case we could
// end up here and the values are equal if the type has zero fields. // end up here and the values are equal if the type has zero fields.
return ty.structFieldCount() != 0; return ty.structFieldCount() != 0;
}, },
@ -2072,8 +2055,8 @@ pub const Value = extern union {
field.default_val.hash(field.ty, hasher); field.default_val.hash(field.ty, hasher);
} }
}, },
.@"struct" => { .aggregate => {
const field_values = val.castTag(.@"struct").?.data; const field_values = val.castTag(.aggregate).?.data;
for (field_values) |field_val, i| { for (field_values) |field_val, i| {
field_val.hash(fields[i].ty, hasher); field_val.hash(fields[i].ty, hasher);
} }
@ -2190,19 +2173,12 @@ pub const Value = extern union {
if (val.isComptimeMutablePtr()) return true; if (val.isComptimeMutablePtr()) return true;
switch (val.tag()) { switch (val.tag()) {
.repeated => return val.castTag(.repeated).?.data.canMutateComptimeVarState(), .repeated => return val.castTag(.repeated).?.data.canMutateComptimeVarState(),
.array => {
const elems = val.cast(Payload.Array).?.data;
for (elems) |elem| {
if (elem.canMutateComptimeVarState()) return true;
}
return false;
},
.eu_payload => return val.castTag(.eu_payload).?.data.canMutateComptimeVarState(), .eu_payload => return val.castTag(.eu_payload).?.data.canMutateComptimeVarState(),
.eu_payload_ptr => return val.castTag(.eu_payload_ptr).?.data.canMutateComptimeVarState(), .eu_payload_ptr => return val.castTag(.eu_payload_ptr).?.data.canMutateComptimeVarState(),
.opt_payload => return val.castTag(.opt_payload).?.data.canMutateComptimeVarState(), .opt_payload => return val.castTag(.opt_payload).?.data.canMutateComptimeVarState(),
.opt_payload_ptr => return val.castTag(.opt_payload_ptr).?.data.canMutateComptimeVarState(), .opt_payload_ptr => return val.castTag(.opt_payload_ptr).?.data.canMutateComptimeVarState(),
.@"struct" => { .aggregate => {
const fields = val.cast(Payload.Struct).?.data; const fields = val.castTag(.aggregate).?.data;
for (fields) |field| { for (fields) |field| {
if (field.canMutateComptimeVarState()) return true; if (field.canMutateComptimeVarState()) return true;
} }
@ -2302,11 +2278,6 @@ pub const Value = extern union {
.empty_array_sentinel, .empty_array_sentinel,
=> return markReferencedDeclsAlive(val.cast(Payload.SubValue).?.data), => return markReferencedDeclsAlive(val.cast(Payload.SubValue).?.data),
.array => {
for (val.cast(Payload.Array).?.data) |elem_val| {
markReferencedDeclsAlive(elem_val);
}
},
.slice => { .slice => {
const slice = val.cast(Payload.Slice).?.data; const slice = val.cast(Payload.Slice).?.data;
markReferencedDeclsAlive(slice.ptr); markReferencedDeclsAlive(slice.ptr);
@ -2321,8 +2292,8 @@ pub const Value = extern union {
const field_ptr = val.cast(Payload.FieldPtr).?.data; const field_ptr = val.cast(Payload.FieldPtr).?.data;
return markReferencedDeclsAlive(field_ptr.container_ptr); return markReferencedDeclsAlive(field_ptr.container_ptr);
}, },
.@"struct" => { .aggregate => {
for (val.cast(Payload.Struct).?.data) |field_val| { for (val.castTag(.aggregate).?.data) |field_val| {
markReferencedDeclsAlive(field_val); markReferencedDeclsAlive(field_val);
} }
}, },
@ -2405,7 +2376,7 @@ pub const Value = extern union {
// No matter the index; all the elements are the same! // No matter the index; all the elements are the same!
.repeated => return val.castTag(.repeated).?.data, .repeated => return val.castTag(.repeated).?.data,
.array => return val.castTag(.array).?.data[index], .aggregate => return val.castTag(.aggregate).?.data[index],
.slice => return val.castTag(.slice).?.data.ptr.elemValueAdvanced(index, arena, buffer), .slice => return val.castTag(.slice).?.data.ptr.elemValueAdvanced(index, arena, buffer),
.decl_ref => return val.castTag(.decl_ref).?.data.val.elemValueAdvanced(index, arena, buffer), .decl_ref => return val.castTag(.decl_ref).?.data.val.elemValueAdvanced(index, arena, buffer),
@ -2426,8 +2397,8 @@ pub const Value = extern union {
pub fn fieldValue(val: Value, allocator: Allocator, index: usize) error{OutOfMemory}!Value { pub fn fieldValue(val: Value, allocator: Allocator, index: usize) error{OutOfMemory}!Value {
_ = allocator; _ = allocator;
switch (val.tag()) { switch (val.tag()) {
.@"struct" => { .aggregate => {
const field_values = val.castTag(.@"struct").?.data; const field_values = val.castTag(.aggregate).?.data;
return field_values[index]; return field_values[index];
}, },
.@"union" => { .@"union" => {
@ -4199,8 +4170,10 @@ pub const Value = extern union {
data: []const u8, data: []const u8,
}; };
pub const Array = struct { pub const Aggregate = struct {
base: Payload, base: Payload,
/// Field values. The types are according to the struct or array type.
/// The length is provided here so that copying a Value does not depend on the Type.
data: []Value, data: []Value,
}; };
@ -4298,15 +4271,6 @@ pub const Value = extern union {
}, },
}; };
pub const Struct = struct {
pub const base_tag = Tag.@"struct";
base: Payload = .{ .tag = base_tag },
/// Field values. The types are according to the struct type.
/// The length is provided here so that copying a Value does not depend on the Type.
data: []Value,
};
pub const Union = struct { pub const Union = struct {
pub const base_tag = Tag.@"union"; pub const base_tag = Tag.@"union";

View File

@ -129,7 +129,11 @@ test "tuple initializer for var" {
} }
test "array-like initializer for tuple types" { test "array-like initializer for tuple types" {
if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
const T = @Type(.{ const T = @Type(.{
.Struct = .{ .Struct = .{