mirror of
https://github.com/ziglang/zig.git
synced 2025-12-23 22:53:06 +00:00
Merge pull request #22979 from mlugg/remove-legacy-coercions
Sema: remove legacy coercion
This commit is contained in:
commit
c76f451abc
@ -112,17 +112,17 @@ pub const DecoderState = struct {
|
||||
.lzma_props = lzma_props,
|
||||
.unpacked_size = unpacked_size,
|
||||
.literal_probs = try Vec2D(u16).init(allocator, 0x400, .{ @as(usize, 1) << (lzma_props.lc + lzma_props.lp), 0x300 }),
|
||||
.pos_slot_decoder = .{.{}} ** 4,
|
||||
.pos_slot_decoder = @splat(.{}),
|
||||
.align_decoder = .{},
|
||||
.pos_decoders = .{0x400} ** 115,
|
||||
.is_match = .{0x400} ** 192,
|
||||
.is_rep = .{0x400} ** 12,
|
||||
.is_rep_g0 = .{0x400} ** 12,
|
||||
.is_rep_g1 = .{0x400} ** 12,
|
||||
.is_rep_g2 = .{0x400} ** 12,
|
||||
.is_rep_0long = .{0x400} ** 192,
|
||||
.pos_decoders = @splat(0x400),
|
||||
.is_match = @splat(0x400),
|
||||
.is_rep = @splat(0x400),
|
||||
.is_rep_g0 = @splat(0x400),
|
||||
.is_rep_g1 = @splat(0x400),
|
||||
.is_rep_g2 = @splat(0x400),
|
||||
.is_rep_0long = @splat(0x400),
|
||||
.state = 0,
|
||||
.rep = .{0} ** 4,
|
||||
.rep = @splat(0),
|
||||
.len_decoder = .{},
|
||||
.rep_len_decoder = .{},
|
||||
};
|
||||
@ -145,15 +145,15 @@ pub const DecoderState = struct {
|
||||
self.lzma_props = new_props;
|
||||
for (&self.pos_slot_decoder) |*t| t.reset();
|
||||
self.align_decoder.reset();
|
||||
self.pos_decoders = .{0x400} ** 115;
|
||||
self.is_match = .{0x400} ** 192;
|
||||
self.is_rep = .{0x400} ** 12;
|
||||
self.is_rep_g0 = .{0x400} ** 12;
|
||||
self.is_rep_g1 = .{0x400} ** 12;
|
||||
self.is_rep_g2 = .{0x400} ** 12;
|
||||
self.is_rep_0long = .{0x400} ** 192;
|
||||
self.pos_decoders = @splat(0x400);
|
||||
self.is_match = @splat(0x400);
|
||||
self.is_rep = @splat(0x400);
|
||||
self.is_rep_g0 = @splat(0x400);
|
||||
self.is_rep_g1 = @splat(0x400);
|
||||
self.is_rep_g2 = @splat(0x400);
|
||||
self.is_rep_0long = @splat(0x400);
|
||||
self.state = 0;
|
||||
self.rep = .{0} ** 4;
|
||||
self.rep = @splat(0);
|
||||
self.len_decoder.reset();
|
||||
self.rep_len_decoder.reset();
|
||||
}
|
||||
|
||||
@ -120,7 +120,7 @@ pub const RangeDecoder = struct {
|
||||
|
||||
pub fn BitTree(comptime num_bits: usize) type {
|
||||
return struct {
|
||||
probs: [1 << num_bits]u16 = .{0x400} ** (1 << num_bits),
|
||||
probs: [1 << num_bits]u16 = @splat(0x400),
|
||||
|
||||
const Self = @This();
|
||||
|
||||
@ -151,8 +151,8 @@ pub fn BitTree(comptime num_bits: usize) type {
|
||||
pub const LenDecoder = struct {
|
||||
choice: u16 = 0x400,
|
||||
choice2: u16 = 0x400,
|
||||
low_coder: [16]BitTree(3) = .{.{}} ** 16,
|
||||
mid_coder: [16]BitTree(3) = .{.{}} ** 16,
|
||||
low_coder: [16]BitTree(3) = @splat(.{}),
|
||||
mid_coder: [16]BitTree(3) = @splat(.{}),
|
||||
high_coder: BitTree(8) = .{},
|
||||
|
||||
pub fn decode(
|
||||
|
||||
112
src/Sema.zig
112
src/Sema.zig
@ -30053,8 +30053,8 @@ fn coerceExtra(
|
||||
else => {},
|
||||
},
|
||||
.@"struct" => blk: {
|
||||
if (inst_ty.isTuple(zcu)) {
|
||||
return sema.coerceTupleToStruct(block, dest_ty, inst, inst_src) catch |err| switch (err) {
|
||||
if (dest_ty.isTuple(zcu) and inst_ty.isTuple(zcu)) {
|
||||
return sema.coerceTupleToTuple(block, dest_ty, inst, inst_src) catch |err| switch (err) {
|
||||
error.NotCoercible => break :blk,
|
||||
else => |e| return e,
|
||||
};
|
||||
@ -32135,114 +32135,6 @@ fn coerceTupleToArrayPtrs(
|
||||
return ptr_array;
|
||||
}
|
||||
|
||||
/// Handles both tuples and anon struct literals. Coerces field-wise. Reports
|
||||
/// errors for both extra fields and missing fields.
|
||||
fn coerceTupleToStruct(
|
||||
sema: *Sema,
|
||||
block: *Block,
|
||||
struct_ty: Type,
|
||||
inst: Air.Inst.Ref,
|
||||
inst_src: LazySrcLoc,
|
||||
) !Air.Inst.Ref {
|
||||
const pt = sema.pt;
|
||||
const zcu = pt.zcu;
|
||||
const ip = &zcu.intern_pool;
|
||||
try struct_ty.resolveFields(pt);
|
||||
try struct_ty.resolveStructFieldInits(pt);
|
||||
|
||||
if (struct_ty.isTuple(zcu)) {
|
||||
return sema.coerceTupleToTuple(block, struct_ty, inst, inst_src);
|
||||
}
|
||||
|
||||
const struct_type = zcu.typeToStruct(struct_ty).?;
|
||||
const field_vals = try sema.arena.alloc(InternPool.Index, struct_type.field_types.len);
|
||||
const field_refs = try sema.arena.alloc(Air.Inst.Ref, field_vals.len);
|
||||
@memset(field_refs, .none);
|
||||
|
||||
const inst_ty = sema.typeOf(inst);
|
||||
var runtime_src: ?LazySrcLoc = null;
|
||||
const field_count = switch (ip.indexToKey(inst_ty.toIntern())) {
|
||||
.tuple_type => |tuple| tuple.types.len,
|
||||
.struct_type => ip.loadStructType(inst_ty.toIntern()).field_types.len,
|
||||
else => unreachable,
|
||||
};
|
||||
for (0..field_count) |tuple_field_index| {
|
||||
const field_src = inst_src; // TODO better source location
|
||||
const field_name = inst_ty.structFieldName(tuple_field_index, zcu).unwrap() orelse
|
||||
try ip.getOrPutStringFmt(sema.gpa, pt.tid, "{d}", .{tuple_field_index}, .no_embedded_nulls);
|
||||
|
||||
const struct_field_index = try sema.structFieldIndex(block, struct_ty, field_name, field_src);
|
||||
const struct_field_ty = Type.fromInterned(struct_type.field_types.get(ip)[struct_field_index]);
|
||||
const elem_ref = try sema.tupleField(block, inst_src, inst, field_src, @intCast(tuple_field_index));
|
||||
const coerced = try sema.coerce(block, struct_field_ty, elem_ref, field_src);
|
||||
field_refs[struct_field_index] = coerced;
|
||||
if (struct_type.fieldIsComptime(ip, struct_field_index)) {
|
||||
const init_val = try sema.resolveValue(coerced) orelse {
|
||||
return sema.failWithNeededComptime(block, field_src, .{ .simple = .stored_to_comptime_field });
|
||||
};
|
||||
|
||||
const field_init = Value.fromInterned(struct_type.field_inits.get(ip)[struct_field_index]);
|
||||
if (!init_val.eql(field_init, struct_field_ty, pt.zcu)) {
|
||||
return sema.failWithInvalidComptimeFieldStore(block, field_src, inst_ty, tuple_field_index);
|
||||
}
|
||||
}
|
||||
if (runtime_src == null) {
|
||||
if (try sema.resolveValue(coerced)) |field_val| {
|
||||
field_vals[struct_field_index] = field_val.toIntern();
|
||||
} else {
|
||||
runtime_src = field_src;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Populate default field values and report errors for missing fields.
|
||||
var root_msg: ?*Zcu.ErrorMsg = null;
|
||||
errdefer if (root_msg) |msg| msg.destroy(sema.gpa);
|
||||
|
||||
for (field_refs, 0..) |*field_ref, i| {
|
||||
if (field_ref.* != .none) continue;
|
||||
|
||||
const field_name = struct_type.field_names.get(ip)[i];
|
||||
const field_default_val = struct_type.fieldInit(ip, i);
|
||||
const field_src = inst_src; // TODO better source location
|
||||
if (field_default_val == .none) {
|
||||
const template = "missing struct field: {}";
|
||||
const args = .{field_name.fmt(ip)};
|
||||
if (root_msg) |msg| {
|
||||
try sema.errNote(field_src, msg, template, args);
|
||||
} else {
|
||||
root_msg = try sema.errMsg(field_src, template, args);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (runtime_src == null) {
|
||||
field_vals[i] = field_default_val;
|
||||
} else {
|
||||
field_ref.* = Air.internedToRef(field_default_val);
|
||||
}
|
||||
}
|
||||
|
||||
if (root_msg) |msg| {
|
||||
try sema.addDeclaredHereNote(msg, struct_ty);
|
||||
root_msg = null;
|
||||
return sema.failWithOwnedErrorMsg(block, msg);
|
||||
}
|
||||
|
||||
if (runtime_src) |rs| {
|
||||
try sema.requireRuntimeBlock(block, inst_src, rs);
|
||||
return block.addAggregateInit(struct_ty, field_refs);
|
||||
}
|
||||
|
||||
const struct_val = try pt.intern(.{ .aggregate = .{
|
||||
.ty = struct_ty.toIntern(),
|
||||
.storage = .{ .elems = field_vals },
|
||||
} });
|
||||
// TODO: figure out InternPool removals for incremental compilation
|
||||
//errdefer ip.remove(struct_val);
|
||||
|
||||
return Air.internedToRef(struct_val);
|
||||
}
|
||||
|
||||
fn coerceTupleToTuple(
|
||||
sema: *Sema,
|
||||
block: *Block,
|
||||
|
||||
@ -405,7 +405,7 @@ test "tuple of struct concatenation and coercion to array" {
|
||||
const SomeStruct = struct { array: [4]StructWithDefault };
|
||||
|
||||
const value1 = SomeStruct{ .array = .{StructWithDefault{}} ++ [_]StructWithDefault{.{}} ** 3 };
|
||||
const value2 = SomeStruct{ .array = .{.{}} ++ [_]StructWithDefault{.{}} ** 3 };
|
||||
const value2 = SomeStruct{ .array = .{ .{}, .{}, .{}, .{} } };
|
||||
|
||||
try expectEqual(value1, value2);
|
||||
}
|
||||
|
||||
21
test/cases/compile_errors/coerce_empty_tuple_to_struct.zig
Normal file
21
test/cases/compile_errors/coerce_empty_tuple_to_struct.zig
Normal file
@ -0,0 +1,21 @@
|
||||
const empty = .{};
|
||||
|
||||
const Foo = struct {};
|
||||
const foo: Foo = empty;
|
||||
|
||||
const Bar = struct { a: u32 };
|
||||
const bar: Bar = empty;
|
||||
|
||||
comptime {
|
||||
_ = foo;
|
||||
}
|
||||
comptime {
|
||||
_ = bar;
|
||||
}
|
||||
|
||||
// error
|
||||
//
|
||||
// :4:18: error: expected type 'tmp.Foo', found '@TypeOf(.{})'
|
||||
// :3:13: note: struct declared here
|
||||
// :7:18: error: expected type 'tmp.Bar', found '@TypeOf(.{})'
|
||||
// :6:13: note: struct declared here
|
||||
@ -7,7 +7,6 @@ export fn entry() void {
|
||||
}
|
||||
|
||||
// error
|
||||
// target=native
|
||||
//
|
||||
// :6:31: error: no field named '0' in struct 'tmp.S'
|
||||
// :6:31: error: expected type 'tmp.S', found 'struct { comptime void = {} }'
|
||||
// :1:11: note: struct declared here
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user