@@ -2649,7 +2649,13 @@ pub fn analyzeAsAlign(
2649
2649
src: LazySrcLoc,
2650
2650
air_ref: Air.Inst.Ref,
2651
2651
) !Alignment {
2652
- const alignment_big = try sema.analyzeAsInt(block, src, air_ref, align_ty, .{ .simple = .@"align" });
2652
+ const alignment_big = try sema.analyzeAsInt(
2653
+ block,
2654
+ src,
2655
+ air_ref,
2656
+ align_ty,
2657
+ .{ .simple = .@"align" },
2658
+ );
2653
2659
return sema.validateAlign(block, src, alignment_big);
2654
2660
}
2655
2661
@@ -18817,7 +18823,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
18817
18823
const abi_align: Alignment = if (inst_data.flags.has_align) blk: {
18818
18824
const ref: Zir.Inst.Ref = @enumFromInt(sema.code.extra[extra_i]);
18819
18825
extra_i += 1;
18820
- const coerced = try sema.coerce(block, .u32 , try sema.resolveInst(ref), align_src);
18826
+ const coerced = try sema.coerce(block, align_ty , try sema.resolveInst(ref), align_src);
18821
18827
const val = try sema.resolveConstDefinedValue(block, align_src, coerced, .{ .simple = .@"align" });
18822
18828
// Check if this happens to be the lazy alignment of our element type, in
18823
18829
// which case we can make this 0 without resolving it.
@@ -20335,15 +20341,11 @@ fn zirReify(
20335
20341
try ip.getOrPutString(gpa, pt.tid, "sentinel_ptr", .no_embedded_nulls),
20336
20342
).?);
20337
20343
20338
- if (!try sema.intFitsInType(alignment_val, .u32 , null)) {
20339
- return sema.fail(block, src, "alignment must fit in 'u32 '", .{});
20344
+ if (!try sema.intFitsInType(alignment_val, align_ty , null)) {
20345
+ return sema.fail(block, src, "alignment must fit in '{f} '", .{align_ty.fmt(pt) });
20340
20346
}
20341
-
20342
20347
const alignment_val_int = try alignment_val.toUnsignedIntSema(pt);
20343
- if (alignment_val_int > 0 and !math.isPowerOfTwo(alignment_val_int)) {
20344
- return sema.fail(block, src, "alignment value '{d}' is not a power of two or zero", .{alignment_val_int});
20345
- }
20346
- const abi_align = Alignment.fromByteUnits(alignment_val_int);
20348
+ const abi_align = try sema.validateAlign(block, src, alignment_val_int);
20347
20349
20348
20350
const elem_ty = child_val.toType();
20349
20351
if (abi_align != .none) {
@@ -20920,8 +20922,6 @@ fn reifyUnion(
20920
20922
std.hash.autoHash(&hasher, opt_tag_type_val.toIntern());
20921
20923
std.hash.autoHash(&hasher, fields_len);
20922
20924
20923
- var any_aligns = false;
20924
-
20925
20925
for (0..fields_len) |field_idx| {
20926
20926
const field_info = try fields_val.elemValue(pt, field_idx);
20927
20927
@@ -20930,16 +20930,11 @@ fn reifyUnion(
20930
20930
const field_align_val = try sema.resolveLazyValue(try field_info.fieldValue(pt, 2));
20931
20931
20932
20932
const field_name = try sema.sliceToIpString(block, src, field_name_val, .{ .simple = .union_field_name });
20933
-
20934
20933
std.hash.autoHash(&hasher, .{
20935
20934
field_name,
20936
20935
field_type_val.toIntern(),
20937
20936
field_align_val.toIntern(),
20938
20937
});
20939
-
20940
- if (field_align_val.toUnsignedInt(zcu) != 0) {
20941
- any_aligns = true;
20942
- }
20943
20938
}
20944
20939
20945
20940
const tracked_inst = try block.trackZir(inst);
@@ -20956,7 +20951,7 @@ fn reifyUnion(
20956
20951
true => .safety,
20957
20952
false => .none,
20958
20953
},
20959
- .any_aligned_fields = any_aligns ,
20954
+ .any_aligned_fields = layout != .@"packed" ,
20960
20955
.requires_comptime = .unknown,
20961
20956
.assumed_runtime_bits = false,
20962
20957
.assumed_pointer_aligned = false,
@@ -20989,8 +20984,7 @@ fn reifyUnion(
20989
20984
);
20990
20985
wip_ty.setName(ip, type_name.name, type_name.nav);
20991
20986
20992
- const field_types = try sema.arena.alloc(InternPool.Index, fields_len);
20993
- const field_aligns = if (any_aligns) try sema.arena.alloc(InternPool.Alignment, fields_len) else undefined;
20987
+ const loaded_union = ip.loadUnionType(wip_ty.index);
20994
20988
20995
20989
const enum_tag_ty, const has_explicit_tag = if (opt_tag_type_val.optionalValue(zcu)) |tag_type_val| tag_ty: {
20996
20990
switch (ip.indexToKey(tag_type_val.toIntern())) {
@@ -21003,11 +20997,12 @@ fn reifyUnion(
21003
20997
const tag_ty_fields_len = enum_tag_ty.enumFieldCount(zcu);
21004
20998
var seen_tags = try std.DynamicBitSetUnmanaged.initEmpty(sema.arena, tag_ty_fields_len);
21005
20999
21006
- for (field_types, 0..) |*field_ty, field_idx| {
21000
+ for (0..fields_len ) |field_idx| {
21007
21001
const field_info = try fields_val.elemValue(pt, field_idx);
21008
21002
21009
21003
const field_name_val = try field_info.fieldValue(pt, 0);
21010
21004
const field_type_val = try field_info.fieldValue(pt, 1);
21005
+ const field_alignment_val = try field_info.fieldValue(pt, 2);
21011
21006
21012
21007
// Don't pass a reason; first loop acts as an assertion that this is valid.
21013
21008
const field_name = try sema.sliceToIpString(block, src, field_name_val, undefined);
@@ -21024,14 +21019,12 @@ fn reifyUnion(
21024
21019
}
21025
21020
seen_tags.set(enum_index);
21026
21021
21027
- field_ty.* = field_type_val.toIntern();
21028
- if (any_aligns) {
21029
- const byte_align = try (try field_info.fieldValue(pt, 2)).toUnsignedIntSema(pt);
21030
- if (byte_align > 0 and !math.isPowerOfTwo(byte_align)) {
21031
- // TODO: better source location
21032
- return sema.fail(block, src, "alignment value '{d}' is not a power of two or zero", .{byte_align});
21033
- }
21034
- field_aligns[field_idx] = Alignment.fromByteUnits(byte_align);
21022
+ loaded_union.field_types.get(ip)[field_idx] = field_type_val.toIntern();
21023
+ const byte_align = try field_alignment_val.toUnsignedIntSema(pt);
21024
+ if (layout == .@"packed") {
21025
+ if (byte_align != 0) return sema.fail(block, src, "alignment of a packed union field must be set to 0", .{});
21026
+ } else {
21027
+ loaded_union.field_aligns.get(ip)[field_idx] = try sema.validateAlign(block, src, byte_align);
21035
21028
}
21036
21029
}
21037
21030
@@ -21055,11 +21048,12 @@ fn reifyUnion(
21055
21048
var field_names: std.AutoArrayHashMapUnmanaged(InternPool.NullTerminatedString, void) = .empty;
21056
21049
try field_names.ensureTotalCapacity(sema.arena, fields_len);
21057
21050
21058
- for (field_types, 0..) |*field_ty, field_idx| {
21051
+ for (0..fields_len ) |field_idx| {
21059
21052
const field_info = try fields_val.elemValue(pt, field_idx);
21060
21053
21061
21054
const field_name_val = try field_info.fieldValue(pt, 0);
21062
21055
const field_type_val = try field_info.fieldValue(pt, 1);
21056
+ const field_alignment_val = try field_info.fieldValue(pt, 2);
21063
21057
21064
21058
// Don't pass a reason; first loop acts as an assertion that this is valid.
21065
21059
const field_name = try sema.sliceToIpString(block, src, field_name_val, undefined);
@@ -21069,14 +21063,12 @@ fn reifyUnion(
21069
21063
return sema.fail(block, src, "duplicate union field {f}", .{field_name.fmt(ip)});
21070
21064
}
21071
21065
21072
- field_ty.* = field_type_val.toIntern();
21073
- if (any_aligns) {
21074
- const byte_align = try (try field_info.fieldValue(pt, 2)).toUnsignedIntSema(pt);
21075
- if (byte_align > 0 and !math.isPowerOfTwo(byte_align)) {
21076
- // TODO: better source location
21077
- return sema.fail(block, src, "alignment value '{d}' is not a power of two or zero", .{byte_align});
21078
- }
21079
- field_aligns[field_idx] = Alignment.fromByteUnits(byte_align);
21066
+ loaded_union.field_types.get(ip)[field_idx] = field_type_val.toIntern();
21067
+ const byte_align = try field_alignment_val.toUnsignedIntSema(pt);
21068
+ if (layout == .@"packed") {
21069
+ if (byte_align != 0) return sema.fail(block, src, "alignment of a packed union field must be set to 0", .{});
21070
+ } else {
21071
+ loaded_union.field_aligns.get(ip)[field_idx] = try sema.validateAlign(block, src, byte_align);
21080
21072
}
21081
21073
}
21082
21074
@@ -21085,7 +21077,7 @@ fn reifyUnion(
21085
21077
};
21086
21078
errdefer if (!has_explicit_tag) ip.remove(pt.tid, enum_tag_ty); // remove generated tag type on error
21087
21079
21088
- for (field_types) |field_ty_ip| {
21080
+ for (loaded_union. field_types.get(ip) ) |field_ty_ip| {
21089
21081
const field_ty: Type = .fromInterned(field_ty_ip);
21090
21082
if (field_ty.zigTypeTag(zcu) == .@"opaque") {
21091
21083
return sema.failWithOwnedErrorMsg(block, msg: {
@@ -21119,11 +21111,6 @@ fn reifyUnion(
21119
21111
}
21120
21112
}
21121
21113
21122
- const loaded_union = ip.loadUnionType(wip_ty.index);
21123
- loaded_union.setFieldTypes(ip, field_types);
21124
- if (any_aligns) {
21125
- loaded_union.setFieldAligns(ip, field_aligns);
21126
- }
21127
21114
loaded_union.setTagType(ip, enum_tag_ty);
21128
21115
loaded_union.setStatus(ip, .have_field_types);
21129
21116
@@ -21276,7 +21263,6 @@ fn reifyStruct(
21276
21263
21277
21264
var any_comptime_fields = false;
21278
21265
var any_default_inits = false;
21279
- var any_aligned_fields = false;
21280
21266
21281
21267
for (0..fields_len) |field_idx| {
21282
21268
const field_info = try fields_val.elemValue(pt, field_idx);
@@ -21311,11 +21297,6 @@ fn reifyStruct(
21311
21297
21312
21298
if (field_is_comptime) any_comptime_fields = true;
21313
21299
if (field_default_value != .none) any_default_inits = true;
21314
- switch (try field_alignment_val.orderAgainstZeroSema(pt)) {
21315
- .eq => {},
21316
- .gt => any_aligned_fields = true,
21317
- .lt => unreachable,
21318
- }
21319
21300
}
21320
21301
21321
21302
const tracked_inst = try block.trackZir(inst);
@@ -21327,7 +21308,7 @@ fn reifyStruct(
21327
21308
.requires_comptime = .unknown,
21328
21309
.any_comptime_fields = any_comptime_fields,
21329
21310
.any_default_inits = any_default_inits,
21330
- .any_aligned_fields = any_aligned_fields ,
21311
+ .any_aligned_fields = layout != .@"packed" ,
21331
21312
.inits_resolved = true,
21332
21313
.key = .{ .reified = .{
21333
21314
.zir_index = tracked_inst,
@@ -21371,21 +21352,14 @@ fn reifyStruct(
21371
21352
return sema.fail(block, src, "duplicate struct field name {f}", .{field_name.fmt(ip)});
21372
21353
}
21373
21354
21374
- if (any_aligned_fields) {
21375
- if (!try sema.intFitsInType(field_alignment_val, .u32, null)) {
21376
- return sema.fail(block, src, "alignment must fit in 'u32'", .{});
21377
- }
21378
-
21379
- const byte_align = try field_alignment_val.toUnsignedIntSema(pt);
21380
- if (byte_align == 0) {
21381
- if (layout != .@"packed") {
21382
- struct_type.field_aligns.get(ip)[field_idx] = .none;
21383
- }
21384
- } else {
21385
- if (layout == .@"packed") return sema.fail(block, src, "alignment in a packed struct field must be set to 0", .{});
21386
- if (!math.isPowerOfTwo(byte_align)) return sema.fail(block, src, "alignment value '{d}' is not a power of two or zero", .{byte_align});
21387
- struct_type.field_aligns.get(ip)[field_idx] = Alignment.fromNonzeroByteUnits(byte_align);
21388
- }
21355
+ if (!try sema.intFitsInType(field_alignment_val, align_ty, null)) {
21356
+ return sema.fail(block, src, "alignment must fit in '{f}'", .{align_ty.fmt(pt)});
21357
+ }
21358
+ const byte_align = try field_alignment_val.toUnsignedIntSema(pt);
21359
+ if (layout == .@"packed") {
21360
+ if (byte_align != 0) return sema.fail(block, src, "alignment of a packed struct field must be set to 0", .{});
21361
+ } else {
21362
+ struct_type.field_aligns.get(ip)[field_idx] = try sema.validateAlign(block, src, byte_align);
21389
21363
}
21390
21364
21391
21365
const field_is_comptime = field_is_comptime_val.toBool();
0 commit comments