...
This commit is contained in:
@@ -4085,12 +4085,35 @@ pub const CodeGen = struct {
|
|||||||
return self.genSliceLiteral(node.data.array_literal, target_ty);
|
return self.genSliceLiteral(node.data.array_literal, target_ty);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Infer source type once for all coercion checks below
|
||||||
|
const src_ty = self.inferType(node);
|
||||||
|
|
||||||
// Array to slice coercion: [N]T → []T
|
// Array to slice coercion: [N]T → []T
|
||||||
if (target_ty.isSlice()) {
|
if (target_ty.isSlice() and src_ty.isArray()) {
|
||||||
const src_ty = self.inferType(node);
|
const arr_info = src_ty.array_type;
|
||||||
if (src_ty.isArray()) {
|
// Get the alloca pointer for the array (not the loaded value)
|
||||||
const arr_info = src_ty.array_type;
|
const arr_alloca = blk: {
|
||||||
// Get the alloca pointer for the array (not the loaded value)
|
if (node.data == .identifier) {
|
||||||
|
if (self.named_values.get(node.data.identifier.name)) |entry| {
|
||||||
|
break :blk entry.ptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (node.data == .field_access) {
|
||||||
|
break :blk try self.genAddressOf(node);
|
||||||
|
}
|
||||||
|
// Fallback: generate the expression and hope it returns a pointer
|
||||||
|
break :blk try self.genExpr(node);
|
||||||
|
};
|
||||||
|
// GEP to get pointer to first element
|
||||||
|
const elem_ptr = self.arrayDecayToPointer(self.typeToLLVM(src_ty), arr_alloca, "arr_data");
|
||||||
|
// Build slice struct {ptr, len}
|
||||||
|
return self.buildFatPointer(self.getStringStructType(), elem_ptr, self.constInt64(arr_info.length));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Array to many-pointer coercion: [N]T → [*]T
|
||||||
|
if (target_ty.isManyPointer() and src_ty.isArray()) {
|
||||||
|
const arr_info = src_ty.array_type;
|
||||||
|
if (std.mem.eql(u8, arr_info.element_name, target_ty.many_pointer_type.element_name)) {
|
||||||
const arr_alloca = blk: {
|
const arr_alloca = blk: {
|
||||||
if (node.data == .identifier) {
|
if (node.data == .identifier) {
|
||||||
if (self.named_values.get(node.data.identifier.name)) |entry| {
|
if (self.named_values.get(node.data.identifier.name)) |entry| {
|
||||||
@@ -4100,52 +4123,22 @@ pub const CodeGen = struct {
|
|||||||
if (node.data == .field_access) {
|
if (node.data == .field_access) {
|
||||||
break :blk try self.genAddressOf(node);
|
break :blk try self.genAddressOf(node);
|
||||||
}
|
}
|
||||||
// Fallback: generate the expression and hope it returns a pointer
|
|
||||||
break :blk try self.genExpr(node);
|
break :blk try self.genExpr(node);
|
||||||
};
|
};
|
||||||
// GEP to get pointer to first element
|
return self.arrayDecayToPointer(self.typeToLLVM(src_ty), arr_alloca, "arr_decay");
|
||||||
const elem_ptr = self.arrayDecayToPointer(self.typeToLLVM(src_ty), arr_alloca, "arr_data");
|
|
||||||
// Build slice struct {ptr, len}
|
|
||||||
return self.buildFatPointer(self.getStringStructType(), elem_ptr, self.constInt64(arr_info.length));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Array to many-pointer coercion: [N]T → [*]T
|
|
||||||
if (target_ty.isManyPointer()) {
|
|
||||||
const src_ty = self.inferType(node);
|
|
||||||
if (src_ty.isArray()) {
|
|
||||||
const arr_info = src_ty.array_type;
|
|
||||||
if (std.mem.eql(u8, arr_info.element_name, target_ty.many_pointer_type.element_name)) {
|
|
||||||
const arr_alloca = blk: {
|
|
||||||
if (node.data == .identifier) {
|
|
||||||
if (self.named_values.get(node.data.identifier.name)) |entry| {
|
|
||||||
break :blk entry.ptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (node.data == .field_access) {
|
|
||||||
break :blk try self.genAddressOf(node);
|
|
||||||
}
|
|
||||||
break :blk try self.genExpr(node);
|
|
||||||
};
|
|
||||||
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 (std.mem.eql(u8, src_ty.slice_type.element_name, target_ty.many_pointer_type.element_name)) {
|
||||||
if (src_ty.isSlice()) {
|
const slice_val = try self.genExpr(node);
|
||||||
if (std.mem.eql(u8, src_ty.slice_type.element_name, target_ty.many_pointer_type.element_name)) {
|
return self.extractValue(slice_val, 0, "slice_decay");
|
||||||
const slice_val = try self.genExpr(node);
|
|
||||||
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()) {
|
||||||
|
|||||||
Reference in New Issue
Block a user