xxx
This commit is contained in:
23
examples/issue-0006.sx
Normal file
23
examples/issue-0006.sx
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
// Issue: match on u8 value with enum result assigned to typed field
|
||||||
|
// The switch value is u8 but case constants are s64 (default int literal type).
|
||||||
|
// Compiler should cast case constants to match the switch value type.
|
||||||
|
// LLVM error: Switch constants must all be same type as switch value!
|
||||||
|
|
||||||
|
out :: (str: string) -> void #builtin;
|
||||||
|
|
||||||
|
Button :: enum {
|
||||||
|
none;
|
||||||
|
left;
|
||||||
|
middle;
|
||||||
|
right;
|
||||||
|
}
|
||||||
|
|
||||||
|
main :: () {
|
||||||
|
val : u8 = 2;
|
||||||
|
result : Button = if val == {
|
||||||
|
case 1: .left;
|
||||||
|
case 2: .middle;
|
||||||
|
case 3: .right;
|
||||||
|
else: .none;
|
||||||
|
};
|
||||||
|
}
|
||||||
39
examples/issue-0007.sx
Normal file
39
examples/issue-0007.sx
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
// Issue: chained method call on struct field operates on a copy
|
||||||
|
// `a.field.method()` where method takes *Self creates a temporary copy of `field`
|
||||||
|
// instead of borrowing `a.field` as a pointer.
|
||||||
|
// The mutation is lost because it modifies the copy, not the original.
|
||||||
|
|
||||||
|
out :: (str: string) -> void #builtin;
|
||||||
|
|
||||||
|
Counter :: struct {
|
||||||
|
value: s64;
|
||||||
|
|
||||||
|
inc :: (self: *Counter) {
|
||||||
|
self.value += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Parent :: struct {
|
||||||
|
counter: Counter;
|
||||||
|
}
|
||||||
|
|
||||||
|
main :: () {
|
||||||
|
p := Parent.{ counter = Counter.{ value = 0 } };
|
||||||
|
|
||||||
|
// This should increment p.counter.value, but the mutation is lost:
|
||||||
|
p.counter.inc();
|
||||||
|
|
||||||
|
if p.counter.value == 0 {
|
||||||
|
out("BUG: p.counter.value is still 0 after inc()\n");
|
||||||
|
} else {
|
||||||
|
out("OK: p.counter.value is 1\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Workaround: take explicit pointer
|
||||||
|
cp := @p.counter;
|
||||||
|
cp.inc();
|
||||||
|
|
||||||
|
if p.counter.value == 1 {
|
||||||
|
out("OK: workaround via pointer works\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,7 @@
|
|||||||
#import c {
|
#import c {
|
||||||
#include "vendors/stb_image/stb_image.h";
|
#include "vendors/stb_image/stb_image.h";
|
||||||
#source "vendors/stb_image/stb_image_impl.c";
|
#source "vendors/stb_image/stb_image_impl.c";
|
||||||
|
|
||||||
|
#include "vendors/stb_image/stb_image_write.h";
|
||||||
|
#source "vendors/stb_image/stb_image_write_impl.c";
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -6333,8 +6333,11 @@ pub const CodeGen = struct {
|
|||||||
return entry.ptr;
|
return entry.ptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Non-identifier expressions (e.g. field access, tuple element):
|
// Field access / index: take address of the lvalue directly (no copy)
|
||||||
// generate value, store into temp alloca, return alloca pointer
|
if (node.data == .field_access or node.data == .index_expr) {
|
||||||
|
return try self.genAddressOf(node);
|
||||||
|
}
|
||||||
|
// Other non-identifier expressions: copy into temp alloca
|
||||||
if (node.data != .identifier) {
|
if (node.data != .identifier) {
|
||||||
const val = try self.genExpr(node);
|
const val = try self.genExpr(node);
|
||||||
const llvm_ty = c.LLVMTypeOf(val);
|
const llvm_ty = c.LLVMTypeOf(val);
|
||||||
@@ -10459,8 +10462,8 @@ pub const CodeGen = struct {
|
|||||||
null;
|
null;
|
||||||
|
|
||||||
const i64_type = self.i64Type();
|
const i64_type = self.i64Type();
|
||||||
// Enum/union case constants use the backing type; bool uses i1; others use i64
|
// Enum/union case constants use the backing type; bool uses i1; others must match subject LLVM type
|
||||||
const case_int_type = if (enum_name) |en| self.getEnumLLVMType(en) else if (union_name) |un| self.getEnumLLVMType(un) else if (subject_ty == .boolean) self.i1Type() else i64_type;
|
const case_int_type = if (enum_name) |en| self.getEnumLLVMType(en) else if (union_name) |un| self.getEnumLLVMType(un) else if (subject_ty == .boolean) self.i1Type() else c.LLVMTypeOf(subject_val);
|
||||||
const merge_bb = self.appendBB("match_end");
|
const merge_bb = self.appendBB("match_end");
|
||||||
|
|
||||||
// Create case basic blocks
|
// Create case basic blocks
|
||||||
|
|||||||
Reference in New Issue
Block a user