aboutsummaryrefslogtreecommitdiff
path: root/src/Sema.zig
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2023-02-27 14:11:29 -0700
committerAndrew Kelley <andrew@ziglang.org>2023-02-27 16:10:48 -0700
commitd399f8a489dd2ae62fae9b805778bfdc697a969b (patch)
tree60df6836102786a1e665dfc92d815a27d6f8c352 /src/Sema.zig
parentb5b634e4e8a2a1fe32fba50ccd175257b4213936 (diff)
parentf6c934677315665c140151b8dd28a56f948205e2 (diff)
downloadzig-d399f8a489dd2ae62fae9b805778bfdc697a969b.tar.gz
zig-d399f8a489dd2ae62fae9b805778bfdc697a969b.zip
Merge remote-tracking branch 'origin/master' into llvm16
Diffstat (limited to 'src/Sema.zig')
-rw-r--r--src/Sema.zig111
1 files changed, 67 insertions, 44 deletions
diff --git a/src/Sema.zig b/src/Sema.zig
index fcdb1ce518..46b47cd23d 100644
--- a/src/Sema.zig
+++ b/src/Sema.zig
@@ -2529,7 +2529,7 @@ fn coerceResultPtr(
_ = try block.addBinOp(.store, new_ptr, null_inst);
return Air.Inst.Ref.void_value;
}
- return sema.bitCast(block, ptr_ty, new_ptr, src);
+ return sema.bitCast(block, ptr_ty, new_ptr, src, null);
}
const trash_inst = trash_block.instructions.pop();
@@ -2545,7 +2545,7 @@ fn coerceResultPtr(
if (try sema.resolveDefinedValue(block, src, new_ptr)) |ptr_val| {
new_ptr = try sema.addConstant(ptr_operand_ty, ptr_val);
} else {
- new_ptr = try sema.bitCast(block, ptr_operand_ty, new_ptr, src);
+ new_ptr = try sema.bitCast(block, ptr_operand_ty, new_ptr, src, null);
}
},
.wrap_optional => {
@@ -5311,7 +5311,6 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr
}
const c_import_pkg = Package.create(
sema.gpa,
- "c_import", // TODO: should we make this unique?
null,
c_import_res.out_zig_path,
) catch |err| switch (err) {
@@ -9655,7 +9654,7 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
.Vector,
=> {},
}
- return sema.bitCast(block, dest_ty, operand, operand_src);
+ return sema.bitCast(block, dest_ty, operand, inst_data.src(), operand_src);
}
fn zirFloatCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
@@ -9888,7 +9887,7 @@ fn zirSwitchCapture(
switch (operand_ty.zigTypeTag()) {
.ErrorSet => if (block.switch_else_err_ty) |some| {
- return sema.bitCast(block, some, operand, operand_src);
+ return sema.bitCast(block, some, operand, operand_src, null);
} else {
try block.addUnreachable(false);
return Air.Inst.Ref.unreachable_value;
@@ -9988,14 +9987,14 @@ fn zirSwitchCapture(
Module.ErrorSet.sortNames(&names);
const else_error_ty = try Type.Tag.error_set_merged.create(sema.arena, names);
- return sema.bitCast(block, else_error_ty, operand, operand_src);
+ return sema.bitCast(block, else_error_ty, operand, operand_src, null);
} else {
const item_ref = try sema.resolveInst(items[0]);
// Previous switch validation ensured this will succeed
const item_val = sema.resolveConstValue(block, .unneeded, item_ref, "") catch unreachable;
const item_ty = try Type.Tag.error_set_single.create(sema.arena, item_val.getError().?);
- return sema.bitCast(block, item_ty, operand, operand_src);
+ return sema.bitCast(block, item_ty, operand, operand_src, null);
}
},
else => {
@@ -11793,8 +11792,9 @@ fn zirImport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
return sema.fail(block, operand_src, "import of file outside package path: '{s}'", .{operand});
},
error.PackageNotFound => {
- const cur_pkg = block.getFileScope().pkg;
- return sema.fail(block, operand_src, "no package named '{s}' available within package '{s}'", .{ operand, cur_pkg.name });
+ const name = try block.getFileScope().pkg.getName(sema.gpa, mod.*);
+ defer sema.gpa.free(name);
+ return sema.fail(block, operand_src, "no package named '{s}' available within package '{s}'", .{ operand, name });
},
else => {
// TODO: these errors are file system errors; make sure an update() will
@@ -19953,7 +19953,7 @@ fn zirAlignCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
} else is_aligned;
try sema.addSafetyCheck(block, ok, .incorrect_alignment);
}
- return sema.bitCast(block, dest_ty, ptr, ptr_src);
+ return sema.bitCast(block, dest_ty, ptr, ptr_src, null);
}
fn zirBitCount(
@@ -21482,24 +21482,32 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
const name_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };
const ptr_src: LazySrcLoc = .{ .node_offset_builtin_call_arg2 = inst_data.src_node };
- const struct_ty = try sema.resolveType(block, ty_src, extra.parent_type);
+ const parent_ty = try sema.resolveType(block, ty_src, extra.parent_type);
const field_name = try sema.resolveConstString(block, name_src, extra.field_name, "field name must be comptime-known");
const field_ptr = try sema.resolveInst(extra.field_ptr);
const field_ptr_ty = sema.typeOf(field_ptr);
- if (struct_ty.zigTypeTag() != .Struct) {
- return sema.fail(block, ty_src, "expected struct type, found '{}'", .{struct_ty.fmt(sema.mod)});
+ if (parent_ty.zigTypeTag() != .Struct and parent_ty.zigTypeTag() != .Union) {
+ return sema.fail(block, ty_src, "expected struct or union type, found '{}'", .{parent_ty.fmt(sema.mod)});
}
- try sema.resolveTypeLayout(struct_ty);
+ try sema.resolveTypeLayout(parent_ty);
- const field_index = if (struct_ty.isTuple()) blk: {
- if (mem.eql(u8, field_name, "len")) {
- return sema.fail(block, src, "cannot get @fieldParentPtr of 'len' field of tuple", .{});
- }
- break :blk try sema.tupleFieldIndex(block, struct_ty, field_name, name_src);
- } else try sema.structFieldIndex(block, struct_ty, field_name, name_src);
+ const field_index = switch (parent_ty.zigTypeTag()) {
+ .Struct => blk: {
+ if (parent_ty.isTuple()) {
+ if (mem.eql(u8, field_name, "len")) {
+ return sema.fail(block, src, "cannot get @fieldParentPtr of 'len' field of tuple", .{});
+ }
+ break :blk try sema.tupleFieldIndex(block, parent_ty, field_name, name_src);
+ } else {
+ break :blk try sema.structFieldIndex(block, parent_ty, field_name, name_src);
+ }
+ },
+ .Union => try sema.unionFieldIndex(block, parent_ty, field_name, name_src),
+ else => unreachable,
+ };
- if (struct_ty.structFieldIsComptime(field_index)) {
+ if (parent_ty.zigTypeTag() == .Struct and parent_ty.structFieldIsComptime(field_index)) {
return sema.fail(block, src, "cannot get @fieldParentPtr of a comptime field", .{});
}
@@ -21507,23 +21515,29 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
const field_ptr_ty_info = field_ptr_ty.ptrInfo().data;
var ptr_ty_data: Type.Payload.Pointer.Data = .{
- .pointee_type = struct_ty.structFieldType(field_index),
+ .pointee_type = parent_ty.structFieldType(field_index),
.mutable = field_ptr_ty_info.mutable,
.@"addrspace" = field_ptr_ty_info.@"addrspace",
};
- if (struct_ty.containerLayout() == .Packed) {
- return sema.fail(block, src, "TODO handle packed structs with @fieldParentPtr", .{});
+ if (parent_ty.containerLayout() == .Packed) {
+ return sema.fail(block, src, "TODO handle packed structs/unions with @fieldParentPtr", .{});
} else {
- ptr_ty_data.@"align" = if (struct_ty.castTag(.@"struct")) |struct_obj| b: {
- break :b struct_obj.data.fields.values()[field_index].abi_align;
- } else 0;
+ ptr_ty_data.@"align" = blk: {
+ if (parent_ty.castTag(.@"struct")) |struct_obj| {
+ break :blk struct_obj.data.fields.values()[field_index].abi_align;
+ } else if (parent_ty.cast(Type.Payload.Union)) |union_obj| {
+ break :blk union_obj.data.fields.values()[field_index].abi_align;
+ } else {
+ break :blk 0;
+ }
+ };
}
const actual_field_ptr_ty = try Type.ptr(sema.arena, sema.mod, ptr_ty_data);
const casted_field_ptr = try sema.coerce(block, actual_field_ptr_ty, field_ptr, ptr_src);
- ptr_ty_data.pointee_type = struct_ty;
+ ptr_ty_data.pointee_type = parent_ty;
const result_ptr = try Type.ptr(sema.arena, sema.mod, ptr_ty_data);
if (try sema.resolveDefinedValue(block, src, casted_field_ptr)) |field_ptr_val| {
@@ -21540,11 +21554,11 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
field_name,
field_index,
payload.data.field_index,
- struct_ty.fmt(sema.mod),
+ parent_ty.fmt(sema.mod),
},
);
errdefer msg.destroy(sema.gpa);
- try sema.addDeclaredHereNote(msg, struct_ty);
+ try sema.addDeclaredHereNote(msg, parent_ty);
break :msg msg;
};
return sema.failWithOwnedErrorMsg(msg);
@@ -24141,8 +24155,9 @@ fn unionFieldVal(
return sema.addConstant(field.ty, tag_and_val.val);
} else {
const old_ty = union_ty.unionFieldType(tag_and_val.tag, sema.mod);
- const new_val = try sema.bitCastVal(block, src, tag_and_val.val, old_ty, field.ty, 0);
- return sema.addConstant(field.ty, new_val);
+ if (try sema.bitCastVal(block, src, tag_and_val.val, old_ty, field.ty, 0)) |new_val| {
+ return sema.addConstant(field.ty, new_val);
+ }
}
},
}
@@ -26514,8 +26529,12 @@ fn storePtrVal(
const abi_size = try sema.usizeCast(block, src, mut_kit.ty.abiSize(target));
const buffer = try sema.gpa.alloc(u8, abi_size);
defer sema.gpa.free(buffer);
- reinterpret.val_ptr.*.writeToMemory(mut_kit.ty, sema.mod, buffer);
- operand_val.writeToMemory(operand_ty, sema.mod, buffer[reinterpret.byte_offset..]);
+ reinterpret.val_ptr.*.writeToMemory(mut_kit.ty, sema.mod, buffer) catch |err| switch (err) {
+ error.ReinterpretDeclRef => unreachable,
+ };
+ operand_val.writeToMemory(operand_ty, sema.mod, buffer[reinterpret.byte_offset..]) catch |err| switch (err) {
+ error.ReinterpretDeclRef => unreachable,
+ };
const arena = mut_kit.beginArena(sema.mod);
defer mut_kit.finishArena(sema.mod);
@@ -27398,6 +27417,7 @@ fn bitCast(
dest_ty_unresolved: Type,
inst: Air.Inst.Ref,
inst_src: LazySrcLoc,
+ operand_src: ?LazySrcLoc,
) CompileError!Air.Inst.Ref {
const dest_ty = try sema.resolveTypeFields(dest_ty_unresolved);
try sema.resolveTypeLayout(dest_ty);
@@ -27419,10 +27439,11 @@ fn bitCast(
}
if (try sema.resolveMaybeUndefVal(inst)) |val| {
- const result_val = try sema.bitCastVal(block, inst_src, val, old_ty, dest_ty, 0);
- return sema.addConstant(dest_ty, result_val);
+ if (try sema.bitCastVal(block, inst_src, val, old_ty, dest_ty, 0)) |result_val| {
+ return sema.addConstant(dest_ty, result_val);
+ }
}
- try sema.requireRuntimeBlock(block, inst_src, null);
+ try sema.requireRuntimeBlock(block, inst_src, operand_src);
return block.addBitCast(dest_ty, inst);
}
@@ -27434,7 +27455,7 @@ fn bitCastVal(
old_ty: Type,
new_ty: Type,
buffer_offset: usize,
-) !Value {
+) !?Value {
const target = sema.mod.getTarget();
if (old_ty.eql(new_ty, sema.mod)) return val;
@@ -27443,8 +27464,10 @@ fn bitCastVal(
const abi_size = try sema.usizeCast(block, src, old_ty.abiSize(target));
const buffer = try sema.gpa.alloc(u8, abi_size);
defer sema.gpa.free(buffer);
- val.writeToMemory(old_ty, sema.mod, buffer);
- return Value.readFromMemory(new_ty, sema.mod, buffer[buffer_offset..], sema.arena);
+ val.writeToMemory(old_ty, sema.mod, buffer) catch |err| switch (err) {
+ error.ReinterpretDeclRef => return null,
+ };
+ return try Value.readFromMemory(new_ty, sema.mod, buffer[buffer_offset..], sema.arena);
}
fn coerceArrayPtrToSlice(
@@ -27551,7 +27574,7 @@ fn coerceCompatiblePtrs(
} else is_non_zero;
try sema.addSafetyCheck(block, ok, .cast_to_null);
}
- return sema.bitCast(block, dest_ty, inst, inst_src);
+ return sema.bitCast(block, dest_ty, inst, inst_src, null);
}
fn coerceEnumToUnion(
@@ -28291,7 +28314,7 @@ fn analyzeRef(
try sema.storePtr(block, src, alloc, operand);
// TODO: Replace with sema.coerce when that supports adding pointer constness.
- return sema.bitCast(block, ptr_type, alloc, src);
+ return sema.bitCast(block, ptr_type, alloc, src, null);
}
fn analyzeLoad(
@@ -32327,11 +32350,11 @@ fn pointerDerefExtra(sema: *Sema, block: *Block, src: LazySrcLoc, ptr_val: Value
// Try the smaller bit-cast first, since that's more efficient than using the larger `parent`
if (deref.pointee) |tv| if (load_sz <= try sema.typeAbiSize(tv.ty))
- return DerefResult{ .val = try sema.bitCastVal(block, src, tv.val, tv.ty, load_ty, 0) };
+ return DerefResult{ .val = (try sema.bitCastVal(block, src, tv.val, tv.ty, load_ty, 0)) orelse return .runtime_load };
// If that fails, try to bit-cast from the largest parent value with a well-defined layout
if (deref.parent) |parent| if (load_sz + parent.byte_offset <= try sema.typeAbiSize(parent.tv.ty))
- return DerefResult{ .val = try sema.bitCastVal(block, src, parent.tv.val, parent.tv.ty, load_ty, parent.byte_offset) };
+ return DerefResult{ .val = (try sema.bitCastVal(block, src, parent.tv.val, parent.tv.ty, load_ty, parent.byte_offset)) orelse return .runtime_load };
if (deref.ty_without_well_defined_layout) |bad_ty| {
// We got no parent for bit-casting, or the parent we got was too small. Either way, the problem