mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 13:54:21 +00:00
stage2: various fixes to get one test passing
* resolve error sets before merging them * implement tupleFieldPtr * make ret_ptr behave like alloc with zero sized types in llvm backend
This commit is contained in:
parent
058e482247
commit
bf3c88b68d
5 changed files with 88 additions and 13 deletions
|
|
@ -1435,7 +1435,7 @@ pub const Fn = struct {
|
||||||
/// All currently known errors that this error set contains. This includes direct additions
|
/// All currently known errors that this error set contains. This includes direct additions
|
||||||
/// via `return error.Foo;`, and possibly also errors that are returned from any dependent functions.
|
/// via `return error.Foo;`, and possibly also errors that are returned from any dependent functions.
|
||||||
/// When the inferred error set is fully resolved, this map contains all the errors that the function might return.
|
/// When the inferred error set is fully resolved, this map contains all the errors that the function might return.
|
||||||
errors: std.StringHashMapUnmanaged(void) = .{},
|
errors: ErrorSet.NameMap = .{},
|
||||||
|
|
||||||
/// Other inferred error sets which this inferred error set should include.
|
/// Other inferred error sets which this inferred error set should include.
|
||||||
inferred_error_sets: std.AutoHashMapUnmanaged(*InferredErrorSet, void) = .{},
|
inferred_error_sets: std.AutoHashMapUnmanaged(*InferredErrorSet, void) = .{},
|
||||||
|
|
|
||||||
84
src/Sema.zig
84
src/Sema.zig
|
|
@ -1613,11 +1613,16 @@ fn zirCoerceResultPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE
|
||||||
//}
|
//}
|
||||||
|
|
||||||
// The last one is always `store`.
|
// The last one is always `store`.
|
||||||
const trash_inst = trash_block.instructions.pop();
|
const trash_inst = trash_block.instructions.items[trash_block.instructions.items.len - 1];
|
||||||
assert(air_tags[trash_inst] == .store);
|
if (air_tags[trash_inst] != .store) {
|
||||||
|
// no store instruction is generated for zero sized types
|
||||||
|
assert((try sema.typeHasOnePossibleValue(block, src, pointee_ty)) != null);
|
||||||
|
} else {
|
||||||
|
trash_block.instructions.items.len -= 1;
|
||||||
assert(trash_inst == sema.air_instructions.len - 1);
|
assert(trash_inst == sema.air_instructions.len - 1);
|
||||||
sema.air_instructions.len -= 1;
|
sema.air_instructions.len -= 1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const ptr_ty = try Type.ptr(sema.arena, .{
|
const ptr_ty = try Type.ptr(sema.arena, .{
|
||||||
.pointee_type = pointee_ty,
|
.pointee_type = pointee_ty,
|
||||||
|
|
@ -5236,6 +5241,22 @@ fn zirMergeErrorSets(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
|
||||||
if (lhs_ty.tag() == .anyerror or rhs_ty.tag() == .anyerror) {
|
if (lhs_ty.tag() == .anyerror or rhs_ty.tag() == .anyerror) {
|
||||||
return Air.Inst.Ref.anyerror_type;
|
return Air.Inst.Ref.anyerror_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (lhs_ty.castTag(.error_set_inferred)) |payload| {
|
||||||
|
try sema.resolveInferredErrorSet(payload.data);
|
||||||
|
// isAnyError might have changed from a false negative to a true positive after resolution.
|
||||||
|
if (lhs_ty.isAnyError()) {
|
||||||
|
return Air.Inst.Ref.anyerror_type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (rhs_ty.castTag(.error_set_inferred)) |payload| {
|
||||||
|
try sema.resolveInferredErrorSet(payload.data);
|
||||||
|
// isAnyError might have changed from a false negative to a true positive after resolution.
|
||||||
|
if (rhs_ty.isAnyError()) {
|
||||||
|
return Air.Inst.Ref.anyerror_type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Resolve both error sets now.
|
// Resolve both error sets now.
|
||||||
const lhs_names = lhs_ty.errorSetNames();
|
const lhs_names = lhs_ty.errorSetNames();
|
||||||
const rhs_names = rhs_ty.errorSetNames();
|
const rhs_names = rhs_ty.errorSetNames();
|
||||||
|
|
@ -6809,6 +6830,10 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (operand_ty.castTag(.error_set_inferred)) |inferred| {
|
||||||
|
try sema.resolveInferredErrorSet(inferred.data);
|
||||||
|
}
|
||||||
|
|
||||||
if (operand_ty.isAnyError()) {
|
if (operand_ty.isAnyError()) {
|
||||||
if (special_prong != .@"else") {
|
if (special_prong != .@"else") {
|
||||||
return sema.fail(
|
return sema.fail(
|
||||||
|
|
@ -14597,6 +14622,12 @@ fn elemPtr(
|
||||||
},
|
},
|
||||||
.Array => return sema.elemPtrArray(block, array_ptr_src, array_ptr, elem_index, elem_index_src),
|
.Array => return sema.elemPtrArray(block, array_ptr_src, array_ptr, elem_index, elem_index_src),
|
||||||
.Vector => return sema.fail(block, src, "TODO implement Sema for elemPtr for vector", .{}),
|
.Vector => return sema.fail(block, src, "TODO implement Sema for elemPtr for vector", .{}),
|
||||||
|
.Struct => {
|
||||||
|
// Tuple field access.
|
||||||
|
const index_val = try sema.resolveConstValue(block, elem_index_src, elem_index);
|
||||||
|
const index = @intCast(u32, index_val.toUnsignedInt());
|
||||||
|
return sema.tupleFieldPtr(block, array_ptr, index, src, elem_index_src);
|
||||||
|
},
|
||||||
else => unreachable,
|
else => unreachable,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -14673,6 +14704,45 @@ fn elemVal(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn tupleFieldPtr(
|
||||||
|
sema: *Sema,
|
||||||
|
block: *Block,
|
||||||
|
tuple_ptr: Air.Inst.Ref,
|
||||||
|
field_index: u32,
|
||||||
|
tuple_src: LazySrcLoc,
|
||||||
|
field_index_src: LazySrcLoc,
|
||||||
|
) CompileError!Air.Inst.Ref {
|
||||||
|
const tuple_ptr_ty = sema.typeOf(tuple_ptr);
|
||||||
|
const tuple_ty = tuple_ptr_ty.childType();
|
||||||
|
const tuple_info = tuple_ty.castTag(.tuple).?.data;
|
||||||
|
|
||||||
|
if (field_index > tuple_info.types.len) {
|
||||||
|
return sema.fail(block, field_index_src, "index {d} outside tuple of length {d}", .{
|
||||||
|
field_index, tuple_info.types.len,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const field_ty = tuple_info.types[field_index];
|
||||||
|
const ptr_field_ty = try Type.ptr(sema.arena, .{
|
||||||
|
.pointee_type = field_ty,
|
||||||
|
.mutable = tuple_ptr_ty.ptrIsMutable(),
|
||||||
|
.@"addrspace" = tuple_ptr_ty.ptrAddressSpace(),
|
||||||
|
});
|
||||||
|
|
||||||
|
if (try sema.resolveMaybeUndefVal(block, tuple_src, tuple_ptr)) |tuple_ptr_val| {
|
||||||
|
return sema.addConstant(
|
||||||
|
ptr_field_ty,
|
||||||
|
try Value.Tag.field_ptr.create(sema.arena, .{
|
||||||
|
.container_ptr = tuple_ptr_val,
|
||||||
|
.field_index = field_index,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
try sema.requireRuntimeBlock(block, tuple_src);
|
||||||
|
return block.addStructFieldPtr(tuple_ptr, field_index, ptr_field_ty);
|
||||||
|
}
|
||||||
|
|
||||||
fn tupleField(
|
fn tupleField(
|
||||||
sema: *Sema,
|
sema: *Sema,
|
||||||
block: *Block,
|
block: *Block,
|
||||||
|
|
@ -15273,9 +15343,8 @@ fn coerceInMemoryAllowedErrorSets(
|
||||||
return .no_match;
|
return .no_match;
|
||||||
}
|
}
|
||||||
|
|
||||||
var it = src_data.errors.keyIterator();
|
for (src_data.errors.keys()) |key| {
|
||||||
while (it.next()) |name_ptr| {
|
if (!dest_ty.errorSetHasField(key)) {
|
||||||
if (!dest_ty.errorSetHasField(name_ptr.*)) {
|
|
||||||
return .no_match;
|
return .no_match;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -17525,9 +17594,8 @@ fn resolveInferredErrorSet(sema: *Sema, inferred_error_set: *Module.Fn.InferredE
|
||||||
try sema.ensureDeclAnalyzed(decl); // To ensure that all dependencies are properly added to the set.
|
try sema.ensureDeclAnalyzed(decl); // To ensure that all dependencies are properly added to the set.
|
||||||
try sema.resolveInferredErrorSet(other_error_set_ptr.*);
|
try sema.resolveInferredErrorSet(other_error_set_ptr.*);
|
||||||
|
|
||||||
var error_it = other_error_set_ptr.*.errors.keyIterator();
|
for (other_error_set_ptr.*.errors.keys()) |key| {
|
||||||
while (error_it.next()) |entry| {
|
try inferred_error_set.errors.put(sema.gpa, key, {});
|
||||||
try inferred_error_set.errors.put(sema.gpa, entry.*, {});
|
|
||||||
}
|
}
|
||||||
if (other_error_set_ptr.*.is_anyerror)
|
if (other_error_set_ptr.*.is_anyerror)
|
||||||
inferred_error_set.is_anyerror = true;
|
inferred_error_set.is_anyerror = true;
|
||||||
|
|
|
||||||
|
|
@ -4025,7 +4025,7 @@ pub const FuncGen = struct {
|
||||||
if (self.liveness.isUnused(inst)) return null;
|
if (self.liveness.isUnused(inst)) return null;
|
||||||
const ptr_ty = self.air.typeOfIndex(inst);
|
const ptr_ty = self.air.typeOfIndex(inst);
|
||||||
const ret_ty = ptr_ty.childType();
|
const ret_ty = ptr_ty.childType();
|
||||||
if (!ret_ty.isFnOrHasRuntimeBits()) return null;
|
if (!ret_ty.isFnOrHasRuntimeBits()) return self.dg.lowerPtrToVoid(ptr_ty);
|
||||||
if (self.ret_ptr) |ret_ptr| return ret_ptr;
|
if (self.ret_ptr) |ret_ptr| return ret_ptr;
|
||||||
const ret_llvm_ty = try self.dg.llvmType(ret_ty);
|
const ret_llvm_ty = try self.dg.llvmType(ret_ty);
|
||||||
const target = self.dg.module.getTarget();
|
const target = self.dg.module.getTarget();
|
||||||
|
|
@ -4845,6 +4845,7 @@ pub const FuncGen = struct {
|
||||||
struct_ptr_ty: Type,
|
struct_ptr_ty: Type,
|
||||||
field_index: u32,
|
field_index: u32,
|
||||||
) !?*const llvm.Value {
|
) !?*const llvm.Value {
|
||||||
|
if (self.liveness.isUnused(inst)) return null;
|
||||||
const struct_ty = struct_ptr_ty.childType();
|
const struct_ty = struct_ptr_ty.childType();
|
||||||
switch (struct_ty.zigTypeTag()) {
|
switch (struct_ty.zigTypeTag()) {
|
||||||
.Struct => switch (struct_ty.containerLayout()) {
|
.Struct => switch (struct_ty.containerLayout()) {
|
||||||
|
|
|
||||||
|
|
@ -3878,6 +3878,12 @@ pub const Type = extern union {
|
||||||
},
|
},
|
||||||
.error_set_merged => ty.castTag(.error_set_merged).?.data.keys(),
|
.error_set_merged => ty.castTag(.error_set_merged).?.data.keys(),
|
||||||
.error_set => ty.castTag(.error_set).?.data.names.keys(),
|
.error_set => ty.castTag(.error_set).?.data.names.keys(),
|
||||||
|
.error_set_inferred => {
|
||||||
|
const inferred_error_set = ty.castTag(.error_set_inferred).?.data;
|
||||||
|
assert(inferred_error_set.is_resolved);
|
||||||
|
assert(!inferred_error_set.is_anyerror);
|
||||||
|
return inferred_error_set.errors.keys();
|
||||||
|
},
|
||||||
else => unreachable,
|
else => unreachable,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -132,6 +132,7 @@ test {
|
||||||
_ = @import("behavior/bugs/3384.zig");
|
_ = @import("behavior/bugs/3384.zig");
|
||||||
_ = @import("behavior/bugs/3742.zig");
|
_ = @import("behavior/bugs/3742.zig");
|
||||||
_ = @import("behavior/bugs/5398.zig");
|
_ = @import("behavior/bugs/5398.zig");
|
||||||
|
_ = @import("behavior/bugs/5487.zig");
|
||||||
_ = @import("behavior/struct_contains_null_ptr_itself.zig");
|
_ = @import("behavior/struct_contains_null_ptr_itself.zig");
|
||||||
_ = @import("behavior/switch_prong_err_enum.zig");
|
_ = @import("behavior/switch_prong_err_enum.zig");
|
||||||
_ = @import("behavior/switch_prong_implicit_cast.zig");
|
_ = @import("behavior/switch_prong_implicit_cast.zig");
|
||||||
|
|
@ -153,7 +154,6 @@ test {
|
||||||
_ = @import("behavior/bugs/1851.zig");
|
_ = @import("behavior/bugs/1851.zig");
|
||||||
_ = @import("behavior/bugs/3779.zig");
|
_ = @import("behavior/bugs/3779.zig");
|
||||||
_ = @import("behavior/bugs/5413.zig");
|
_ = @import("behavior/bugs/5413.zig");
|
||||||
_ = @import("behavior/bugs/5487.zig");
|
|
||||||
_ = @import("behavior/bugs/6456.zig");
|
_ = @import("behavior/bugs/6456.zig");
|
||||||
_ = @import("behavior/bugs/6781.zig");
|
_ = @import("behavior/bugs/6781.zig");
|
||||||
_ = @import("behavior/bugs/7003.zig");
|
_ = @import("behavior/bugs/7003.zig");
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue