This commit is contained in:
agra
2026-02-16 02:08:17 +02:00
parent c8ceceed0f
commit 66034b4fec

View File

@@ -4085,10 +4085,11 @@ pub const CodeGen = struct {
return self.genSliceLiteral(node.data.array_literal, target_ty); return self.genSliceLiteral(node.data.array_literal, target_ty);
} }
// Array to slice coercion: [N]T → []T // Infer source type once for all coercion checks below
if (target_ty.isSlice()) {
const src_ty = self.inferType(node); const src_ty = self.inferType(node);
if (src_ty.isArray()) {
// Array to slice coercion: [N]T → []T
if (target_ty.isSlice() and src_ty.isArray()) {
const arr_info = src_ty.array_type; const arr_info = src_ty.array_type;
// Get the alloca pointer for the array (not the loaded value) // Get the alloca pointer for the array (not the loaded value)
const arr_alloca = blk: { const arr_alloca = blk: {
@@ -4108,12 +4109,9 @@ pub const CodeGen = struct {
// Build slice struct {ptr, len} // Build slice struct {ptr, len}
return self.buildFatPointer(self.getStringStructType(), elem_ptr, self.constInt64(arr_info.length)); return self.buildFatPointer(self.getStringStructType(), elem_ptr, self.constInt64(arr_info.length));
} }
}
// Array to many-pointer coercion: [N]T → [*]T // Array to many-pointer coercion: [N]T → [*]T
if (target_ty.isManyPointer()) { if (target_ty.isManyPointer() and src_ty.isArray()) {
const src_ty = self.inferType(node);
if (src_ty.isArray()) {
const arr_info = src_ty.array_type; const arr_info = src_ty.array_type;
if (std.mem.eql(u8, arr_info.element_name, target_ty.many_pointer_type.element_name)) { if (std.mem.eql(u8, arr_info.element_name, target_ty.many_pointer_type.element_name)) {
const arr_alloca = blk: { const arr_alloca = blk: {
@@ -4130,22 +4128,17 @@ pub const CodeGen = struct {
return self.arrayDecayToPointer(self.typeToLLVM(src_ty), arr_alloca, "arr_decay"); return self.arrayDecayToPointer(self.typeToLLVM(src_ty), arr_alloca, "arr_decay");
} }
} }
}
// Slice to many-pointer coercion: []T → [*]T (extract .ptr from fat pointer) // Slice to many-pointer coercion: []T → [*]T (extract .ptr from fat pointer)
if (target_ty.isManyPointer()) { if (target_ty.isManyPointer() and src_ty.isSlice()) {
const src_ty = self.inferType(node);
if (src_ty.isSlice()) {
if (std.mem.eql(u8, src_ty.slice_type.element_name, target_ty.many_pointer_type.element_name)) { if (std.mem.eql(u8, src_ty.slice_type.element_name, target_ty.many_pointer_type.element_name)) {
const slice_val = try self.genExpr(node); const slice_val = try self.genExpr(node);
return self.extractValue(slice_val, 0, "slice_decay"); return self.extractValue(slice_val, 0, "slice_decay");
} }
} }
}
// Implicit address-of: passing T where *T is expected → auto & // Implicit address-of: passing T where *T is expected → auto &
if (target_ty.isPointer()) { if (target_ty.isPointer()) {
const src_ty = self.inferType(node);
const pointee_name = target_ty.pointer_type.pointee_name; const pointee_name = target_ty.pointer_type.pointee_name;
const src_matches = if (src_ty.isStruct()) const src_matches = if (src_ty.isStruct())
std.mem.eql(u8, src_ty.struct_type, pointee_name) or std.mem.eql(u8, src_ty.struct_type, pointee_name) or
@@ -4170,7 +4163,6 @@ pub const CodeGen = struct {
} }
var val = try self.genExpr(node); var val = try self.genExpr(node);
const src_ty = self.inferType(node);
// Struct literals return alloca pointers — load the value for by-value passing // Struct literals return alloca pointers — load the value for by-value passing
if (src_ty.isStruct() and target_ty.isStruct()) { if (src_ty.isStruct() and target_ty.isStruct()) {