diff --git a/examples/0177-types-array-consts.sx b/examples/0177-types-array-consts.sx new file mode 100644 index 0000000..d6245b3 --- /dev/null +++ b/examples/0177-types-array-consts.sx @@ -0,0 +1,34 @@ +// Array-typed `::` constants are IMMUTABLE GLOBALS: one storage, reads +// GEP it, the emitter marks it constant, dead-global elimination drops +// unused ones. Typed (`K : [4]s64 : .[...]`) and untyped (`A :: .[...]`, +// element type inferred — all ints s64; any float promotes the element +// type to f64 with ints converting exactly; bool/string homogeneous). +// Element shapes cover nested aggregates. Reads are normal array values: +// indexing, .len, by-value copies (independent of the const), passing to +// fixed-array params, and @-address (reads through *[4]s64 — issue 0117). + +#import "modules/std.sx"; + +K : [4]s64 : .[11, 22, 33, 44]; +A :: .[1, 2, 3]; +M :: .[1, 2.2, 3]; +F : [2]f64 : .[1, 2.5]; +S :: .["alpha", "beta"]; +B :: .[true, false, true]; +P :: struct { x, y: s64; } +PTS : [2]P : .[P.{ x = 1, y = 2 }, P.{ x = 3, y = 4 }]; +GRID : [2][2]s64 : .[.[1, 2], .[3, 4]]; + +sum :: (xs: [4]s64) -> s64 { xs[0] + xs[1] + xs[2] + xs[3] } + +main :: () { + print("typed={} untyped={} len={}\n", K[2], A[1], K.len); + print("mixed={} {} {} intfloat={}\n", M[0], M[1], M[2], F[0]); + print("str={} bool={} pt={} grid={}\n", S[1], B[2], PTS[1].y, GRID[1][0]); + k := K; + k[0] = 99; + print("copy={} const={}\n", k[0], K[0]); + print("sum={}\n", sum(K)); + p := @K; + print("via-ptr={}\n", p[2]); +} diff --git a/examples/0837-modules-array-const-no-cross-borrow.sx b/examples/0837-modules-array-const-no-cross-borrow.sx index a93882c..2c033c6 100644 --- a/examples/0837-modules-array-const-no-cross-borrow.sx +++ b/examples/0837-modules-array-const-no-cross-borrow.sx @@ -1,11 +1,11 @@ -// An ARRAY-typed `::` const (`K : [4]s64 : .[...]`) is not a supported -// module-const shape — its own module's read diagnoses cleanly as -// unresolved. The own author OWNS the name: the read must never borrow -// another module's same-named scalar const (which used to type `K[2]` -// against the scalar and panic at LLVM emission). +// An ARRAY-typed `::` const is an immutable global owned by its module. +// Cross-module: the main file's scalar `K : s64 : 4` and h.sx's array +// `K : [4]s64 : .[...]` coexist — each module's bare `K` binds its OWN +// author (h's use_k reads ITS array, main's K stays the scalar 4). // -// Regression (issue 0115). When array `::` consts land, repoint this -// example at the new behavior. +// Regression (issue 0115): h.sx's read used to borrow main's scalar K +// and panic at LLVM emission; before array consts landed (PLAN-CONST-AGG +// step 1) the shape was a clean "unresolved" diagnostic. #import "modules/std.sx"; h :: #import "0837-modules-array-const-no-cross-borrow/h.sx"; @@ -13,5 +13,5 @@ h :: #import "0837-modules-array-const-no-cross-borrow/h.sx"; K : s64 : 4; main :: () { - print("{}\n", h.use_k()); + print("{} {}\n", K, h.use_k()); } diff --git a/examples/1159-diagnostics-array-const-mixed-elements.sx b/examples/1159-diagnostics-array-const-mixed-elements.sx new file mode 100644 index 0000000..af6917a --- /dev/null +++ b/examples/1159-diagnostics-array-const-mixed-elements.sx @@ -0,0 +1,12 @@ +// An untyped array-literal constant infers its element type from the +// elements (ints -> s64; a numeric int/float mix promotes to f64). A +// NON-NUMERIC mix has no unified element type — diagnosed, with the +// annotation as the fix. + +#import "modules/std.sx"; + +BAD :: .["alpha", 1]; + +main :: () { + print("{}\n", BAD[0]); +} diff --git a/examples/1160-diagnostics-array-const-runtime-element.sx b/examples/1160-diagnostics-array-const-runtime-element.sx new file mode 100644 index 0000000..f2d3268 --- /dev/null +++ b/examples/1160-diagnostics-array-const-runtime-element.sx @@ -0,0 +1,12 @@ +// An array constant's elements must be compile-time constants — a call +// (or any runtime expression) in an element slot is diagnosed. `#run` +// is the tool for computed constants. + +#import "modules/std.sx"; + +f :: () -> s64 { 7 } +BAD : [2]s64 : .[1, f()]; + +main :: () { + print("{}\n", BAD[0]); +} diff --git a/examples/1161-diagnostics-array-const-dim-mismatch.sx b/examples/1161-diagnostics-array-const-dim-mismatch.sx new file mode 100644 index 0000000..a13f46c --- /dev/null +++ b/examples/1161-diagnostics-array-const-dim-mismatch.sx @@ -0,0 +1,10 @@ +// A typed array constant's annotation dimension must match the +// initializer's element count. + +#import "modules/std.sx"; + +BAD : [3]s64 : .[1, 2]; + +main :: () { + print("{}\n", BAD[0]); +} diff --git a/examples/expected/0031-basic-local-fn-return.ir b/examples/expected/0031-basic-local-fn-return.ir index 728167f..aa96752 100644 --- a/examples/expected/0031-basic-local-fn-return.ir +++ b/examples/expected/0031-basic-local-fn-return.ir @@ -1,5 +1,5 @@ -@__sx_default_context = internal global { { ptr, ptr, ptr }, ptr } { { ptr, ptr, ptr } { ptr null, ptr @__thunk_CAllocator_Allocator_alloc, ptr @__thunk_CAllocator_Allocator_dealloc }, ptr null } +@__sx_default_context = internal constant { { ptr, ptr, ptr }, ptr } { { ptr, ptr, ptr } { ptr null, ptr @__thunk_CAllocator_Allocator_alloc, ptr @__thunk_CAllocator_Allocator_dealloc }, ptr null } @str = private unnamed_addr constant [2 x i8] c"0\00", align 1 @str.465 = private unnamed_addr constant [2 x i8] c"0\00", align 1 @str.466 = private unnamed_addr constant [5 x i8] c"true\00", align 1 diff --git a/examples/expected/0032-basic-ufcs-return-type.ir b/examples/expected/0032-basic-ufcs-return-type.ir index 5d9cd1e..46d81ed 100644 --- a/examples/expected/0032-basic-ufcs-return-type.ir +++ b/examples/expected/0032-basic-ufcs-return-type.ir @@ -1,5 +1,5 @@ -@__sx_default_context = internal global { { ptr, ptr, ptr }, ptr } { { ptr, ptr, ptr } { ptr null, ptr @__thunk_CAllocator_Allocator_alloc, ptr @__thunk_CAllocator_Allocator_dealloc }, ptr null } +@__sx_default_context = internal constant { { ptr, ptr, ptr }, ptr } { { ptr, ptr, ptr } { ptr null, ptr @__thunk_CAllocator_Allocator_alloc, ptr @__thunk_CAllocator_Allocator_dealloc }, ptr null } @str = private unnamed_addr constant [2 x i8] c"0\00", align 1 @str.465 = private unnamed_addr constant [2 x i8] c"0\00", align 1 @str.466 = private unnamed_addr constant [5 x i8] c"true\00", align 1 diff --git a/examples/expected/0044-basic-default-arg-expansion.ir b/examples/expected/0044-basic-default-arg-expansion.ir index 0e0afc4..e52b9f5 100644 --- a/examples/expected/0044-basic-default-arg-expansion.ir +++ b/examples/expected/0044-basic-default-arg-expansion.ir @@ -1,5 +1,5 @@ -@__sx_default_context = internal global { { ptr, ptr, ptr }, ptr } { { ptr, ptr, ptr } { ptr null, ptr @__thunk_CAllocator_Allocator_alloc, ptr @__thunk_CAllocator_Allocator_dealloc }, ptr null } +@__sx_default_context = internal constant { { ptr, ptr, ptr }, ptr } { { ptr, ptr, ptr } { ptr null, ptr @__thunk_CAllocator_Allocator_alloc, ptr @__thunk_CAllocator_Allocator_dealloc }, ptr null } @str = private unnamed_addr constant [2 x i8] c"0\00", align 1 @str.125 = private unnamed_addr constant [2 x i8] c"0\00", align 1 @str.126 = private unnamed_addr constant [5 x i8] c"true\00", align 1 diff --git a/examples/expected/0107-types-int-cmp-in-float-ternary.ir b/examples/expected/0107-types-int-cmp-in-float-ternary.ir index b030b1c..20c661c 100644 --- a/examples/expected/0107-types-int-cmp-in-float-ternary.ir +++ b/examples/expected/0107-types-int-cmp-in-float-ternary.ir @@ -1,5 +1,5 @@ -@__sx_default_context = internal global { { ptr, ptr, ptr }, ptr } { { ptr, ptr, ptr } { ptr null, ptr @__thunk_CAllocator_Allocator_alloc, ptr @__thunk_CAllocator_Allocator_dealloc }, ptr null } +@__sx_default_context = internal constant { { ptr, ptr, ptr }, ptr } { { ptr, ptr, ptr } { ptr null, ptr @__thunk_CAllocator_Allocator_alloc, ptr @__thunk_CAllocator_Allocator_dealloc }, ptr null } @str = private unnamed_addr constant [2 x i8] c"0\00", align 1 @str.125 = private unnamed_addr constant [2 x i8] c"0\00", align 1 @str.126 = private unnamed_addr constant [5 x i8] c"true\00", align 1 diff --git a/examples/expected/0177-types-array-consts.exit b/examples/expected/0177-types-array-consts.exit new file mode 100644 index 0000000..573541a --- /dev/null +++ b/examples/expected/0177-types-array-consts.exit @@ -0,0 +1 @@ +0 diff --git a/examples/expected/0177-types-array-consts.stderr b/examples/expected/0177-types-array-consts.stderr new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/examples/expected/0177-types-array-consts.stderr @@ -0,0 +1 @@ + diff --git a/examples/expected/0177-types-array-consts.stdout b/examples/expected/0177-types-array-consts.stdout new file mode 100644 index 0000000..9970ebb --- /dev/null +++ b/examples/expected/0177-types-array-consts.stdout @@ -0,0 +1,6 @@ +typed=33 untyped=2 len=4 +mixed=1.000000 2.200000 3.000000 intfloat=1.000000 +str=beta bool=true pt=4 grid=3 +copy=99 const=11 +sum=110 +via-ptr=33 diff --git a/examples/expected/0200-generics-generic.ir b/examples/expected/0200-generics-generic.ir index 97a008e..d65cdc5 100644 --- a/examples/expected/0200-generics-generic.ir +++ b/examples/expected/0200-generics-generic.ir @@ -1,5 +1,5 @@ -@__sx_default_context = internal global { { ptr, ptr, ptr }, ptr } { { ptr, ptr, ptr } { ptr null, ptr @__thunk_CAllocator_Allocator_alloc, ptr @__thunk_CAllocator_Allocator_dealloc }, ptr null } +@__sx_default_context = internal constant { { ptr, ptr, ptr }, ptr } { { ptr, ptr, ptr } { ptr null, ptr @__thunk_CAllocator_Allocator_alloc, ptr @__thunk_CAllocator_Allocator_dealloc }, ptr null } @str = private unnamed_addr constant [2 x i8] c"0\00", align 1 @str.125 = private unnamed_addr constant [2 x i8] c"0\00", align 1 @str.126 = private unnamed_addr constant [5 x i8] c"true\00", align 1 diff --git a/examples/expected/0201-generics-generic-struct.ir b/examples/expected/0201-generics-generic-struct.ir index 12bccc1..ccac0c7 100644 --- a/examples/expected/0201-generics-generic-struct.ir +++ b/examples/expected/0201-generics-generic-struct.ir @@ -1,5 +1,5 @@ -@__sx_default_context = internal global { { ptr, ptr, ptr }, ptr } { { ptr, ptr, ptr } { ptr null, ptr @__thunk_CAllocator_Allocator_alloc, ptr @__thunk_CAllocator_Allocator_dealloc }, ptr null } +@__sx_default_context = internal constant { { ptr, ptr, ptr }, ptr } { { ptr, ptr, ptr } { ptr null, ptr @__thunk_CAllocator_Allocator_alloc, ptr @__thunk_CAllocator_Allocator_dealloc }, ptr null } @str = private unnamed_addr constant [2 x i8] c"0\00", align 1 @str.125 = private unnamed_addr constant [2 x i8] c"0\00", align 1 @str.126 = private unnamed_addr constant [5 x i8] c"true\00", align 1 diff --git a/examples/expected/0301-closures-fn-pointers.ir b/examples/expected/0301-closures-fn-pointers.ir index 3952cdf..6fd6634 100644 --- a/examples/expected/0301-closures-fn-pointers.ir +++ b/examples/expected/0301-closures-fn-pointers.ir @@ -1,5 +1,5 @@ -@__sx_default_context = internal global { { ptr, ptr, ptr }, ptr } { { ptr, ptr, ptr } { ptr null, ptr @__thunk_CAllocator_Allocator_alloc, ptr @__thunk_CAllocator_Allocator_dealloc }, ptr null } +@__sx_default_context = internal constant { { ptr, ptr, ptr }, ptr } { { ptr, ptr, ptr } { ptr null, ptr @__thunk_CAllocator_Allocator_alloc, ptr @__thunk_CAllocator_Allocator_dealloc }, ptr null } @str = private unnamed_addr constant [2 x i8] c"0\00", align 1 @str.125 = private unnamed_addr constant [2 x i8] c"0\00", align 1 @str.126 = private unnamed_addr constant [5 x i8] c"true\00", align 1 diff --git a/examples/expected/0400-protocols-impl-for-builtin.ir b/examples/expected/0400-protocols-impl-for-builtin.ir index dc45201..294bafc 100644 --- a/examples/expected/0400-protocols-impl-for-builtin.ir +++ b/examples/expected/0400-protocols-impl-for-builtin.ir @@ -1,5 +1,5 @@ -@__sx_default_context = internal global { { ptr, ptr, ptr }, ptr } { { ptr, ptr, ptr } { ptr null, ptr @__thunk_CAllocator_Allocator_alloc, ptr @__thunk_CAllocator_Allocator_dealloc }, ptr null } +@__sx_default_context = internal constant { { ptr, ptr, ptr }, ptr } { { ptr, ptr, ptr } { ptr null, ptr @__thunk_CAllocator_Allocator_alloc, ptr @__thunk_CAllocator_Allocator_dealloc }, ptr null } @str = private unnamed_addr constant [2 x i8] c"0\00", align 1 @str.125 = private unnamed_addr constant [2 x i8] c"0\00", align 1 @str.126 = private unnamed_addr constant [5 x i8] c"true\00", align 1 diff --git a/examples/expected/0413-protocols-parameterized-protocol-value.ir b/examples/expected/0413-protocols-parameterized-protocol-value.ir index 73f2f81..7d58051 100644 --- a/examples/expected/0413-protocols-parameterized-protocol-value.ir +++ b/examples/expected/0413-protocols-parameterized-protocol-value.ir @@ -1,5 +1,5 @@ -@__sx_default_context = internal global { { ptr, ptr, ptr }, ptr } { { ptr, ptr, ptr } { ptr null, ptr @__thunk_CAllocator_Allocator_alloc, ptr @__thunk_CAllocator_Allocator_dealloc }, ptr null } +@__sx_default_context = internal constant { { ptr, ptr, ptr }, ptr } { { ptr, ptr, ptr } { ptr null, ptr @__thunk_CAllocator_Allocator_alloc, ptr @__thunk_CAllocator_Allocator_dealloc }, ptr null } @__VL__s64__IntCell__vtable = internal constant { ptr } { ptr @__thunk_IntCell_VL__s64_get } @__VL__string__StrCell__vtable = internal constant { ptr } { ptr @__thunk_StrCell_VL__string_get } @str = private unnamed_addr constant [2 x i8] c"0\00", align 1 diff --git a/examples/expected/0414-protocols-generic-struct-protocol-erase.ir b/examples/expected/0414-protocols-generic-struct-protocol-erase.ir index 2ffd365..9e99380 100644 --- a/examples/expected/0414-protocols-generic-struct-protocol-erase.ir +++ b/examples/expected/0414-protocols-generic-struct-protocol-erase.ir @@ -1,5 +1,5 @@ -@__sx_default_context = internal global { { ptr, ptr, ptr }, ptr } { { ptr, ptr, ptr } { ptr null, ptr @__thunk_CAllocator_Allocator_alloc, ptr @__thunk_CAllocator_Allocator_dealloc }, ptr null } +@__sx_default_context = internal constant { { ptr, ptr, ptr }, ptr } { { ptr, ptr, ptr } { ptr null, ptr @__thunk_CAllocator_Allocator_alloc, ptr @__thunk_CAllocator_Allocator_dealloc }, ptr null } @__VL__s64__IntCell__vtable = internal constant { ptr } { ptr @__thunk_IntCell_VL__s64_get } @__VL__s64__Combined__s64__s64__vtable = internal constant { ptr } { ptr @__thunk_Combined__s64__s64_VL__s64_get } @str = private unnamed_addr constant [2 x i8] c"0\00", align 1 diff --git a/examples/expected/0416-protocols-auto-type-erasure.ir b/examples/expected/0416-protocols-auto-type-erasure.ir index 1c8104f..a14e427 100644 --- a/examples/expected/0416-protocols-auto-type-erasure.ir +++ b/examples/expected/0416-protocols-auto-type-erasure.ir @@ -1,5 +1,5 @@ -@__sx_default_context = internal global { { ptr, ptr, ptr }, ptr } { { ptr, ptr, ptr } { ptr null, ptr @__thunk_CAllocator_Allocator_alloc, ptr @__thunk_CAllocator_Allocator_dealloc }, ptr null } +@__sx_default_context = internal constant { { ptr, ptr, ptr }, ptr } { { ptr, ptr, ptr } { ptr null, ptr @__thunk_CAllocator_Allocator_alloc, ptr @__thunk_CAllocator_Allocator_dealloc }, ptr null } @__Counter__SimpleCounter__vtable = internal constant { ptr, ptr } { ptr @__thunk_SimpleCounter_Counter_inc, ptr @__thunk_SimpleCounter_Counter_get } @str = private unnamed_addr constant [2 x i8] c"0\00", align 1 @str.466 = private unnamed_addr constant [2 x i8] c"0\00", align 1 diff --git a/examples/expected/0507-packs-pack-mono-dedup.ir b/examples/expected/0507-packs-pack-mono-dedup.ir index 26175dd..425c20f 100644 --- a/examples/expected/0507-packs-pack-mono-dedup.ir +++ b/examples/expected/0507-packs-pack-mono-dedup.ir @@ -1,5 +1,5 @@ -@__sx_default_context = internal global { { ptr, ptr, ptr }, ptr } { { ptr, ptr, ptr } { ptr null, ptr @__thunk_CAllocator_Allocator_alloc, ptr @__thunk_CAllocator_Allocator_dealloc }, ptr null } +@__sx_default_context = internal constant { { ptr, ptr, ptr }, ptr } { { ptr, ptr, ptr } { ptr null, ptr @__thunk_CAllocator_Allocator_alloc, ptr @__thunk_CAllocator_Allocator_dealloc }, ptr null } @str = private unnamed_addr constant [2 x i8] c"0\00", align 1 @str.125 = private unnamed_addr constant [2 x i8] c"0\00", align 1 @str.126 = private unnamed_addr constant [5 x i8] c"true\00", align 1 diff --git a/examples/expected/0513-packs-pack-mixed-comptime.ir b/examples/expected/0513-packs-pack-mixed-comptime.ir index 81c6b9e..f8c8ee4 100644 --- a/examples/expected/0513-packs-pack-mixed-comptime.ir +++ b/examples/expected/0513-packs-pack-mixed-comptime.ir @@ -1,5 +1,5 @@ -@__sx_default_context = internal global { { ptr, ptr, ptr }, ptr } { { ptr, ptr, ptr } { ptr null, ptr @__thunk_CAllocator_Allocator_alloc, ptr @__thunk_CAllocator_Allocator_dealloc }, ptr null } +@__sx_default_context = internal constant { { ptr, ptr, ptr }, ptr } { { ptr, ptr, ptr } { ptr null, ptr @__thunk_CAllocator_Allocator_alloc, ptr @__thunk_CAllocator_Allocator_dealloc }, ptr null } @str = private unnamed_addr constant [2 x i8] c"0\00", align 1 @str.125 = private unnamed_addr constant [2 x i8] c"0\00", align 1 @str.126 = private unnamed_addr constant [5 x i8] c"true\00", align 1 diff --git a/examples/expected/0518-packs-pack-value-dispatch.ir b/examples/expected/0518-packs-pack-value-dispatch.ir index b144695..2951ea9 100644 --- a/examples/expected/0518-packs-pack-value-dispatch.ir +++ b/examples/expected/0518-packs-pack-value-dispatch.ir @@ -1,5 +1,5 @@ -@__sx_default_context = internal global { { ptr, ptr, ptr }, ptr } { { ptr, ptr, ptr } { ptr null, ptr @__thunk_CAllocator_Allocator_alloc, ptr @__thunk_CAllocator_Allocator_dealloc }, ptr null } +@__sx_default_context = internal constant { { ptr, ptr, ptr }, ptr } { { ptr, ptr, ptr } { ptr null, ptr @__thunk_CAllocator_Allocator_alloc, ptr @__thunk_CAllocator_Allocator_dealloc }, ptr null } @str = private unnamed_addr constant [2 x i8] c"0\00", align 1 @str.125 = private unnamed_addr constant [2 x i8] c"0\00", align 1 @str.126 = private unnamed_addr constant [5 x i8] c"true\00", align 1 diff --git a/examples/expected/0528-packs-protocol-pack-methods.ir b/examples/expected/0528-packs-protocol-pack-methods.ir index aa59c7d..c1bb8c1 100644 --- a/examples/expected/0528-packs-protocol-pack-methods.ir +++ b/examples/expected/0528-packs-protocol-pack-methods.ir @@ -1,5 +1,5 @@ -@__sx_default_context = internal global { { ptr, ptr, ptr }, ptr } { { ptr, ptr, ptr } { ptr null, ptr @__thunk_CAllocator_Allocator_alloc, ptr @__thunk_CAllocator_Allocator_dealloc }, ptr null } +@__sx_default_context = internal constant { { ptr, ptr, ptr }, ptr } { { ptr, ptr, ptr } { ptr null, ptr @__thunk_CAllocator_Allocator_alloc, ptr @__thunk_CAllocator_Allocator_dealloc }, ptr null } @str = private unnamed_addr constant [2 x i8] c"0\00", align 1 @str.125 = private unnamed_addr constant [2 x i8] c"0\00", align 1 @str.126 = private unnamed_addr constant [5 x i8] c"true\00", align 1 diff --git a/examples/expected/0837-modules-array-const-no-cross-borrow.exit b/examples/expected/0837-modules-array-const-no-cross-borrow.exit index d00491f..573541a 100644 --- a/examples/expected/0837-modules-array-const-no-cross-borrow.exit +++ b/examples/expected/0837-modules-array-const-no-cross-borrow.exit @@ -1 +1 @@ -1 +0 diff --git a/examples/expected/0837-modules-array-const-no-cross-borrow.stderr b/examples/expected/0837-modules-array-const-no-cross-borrow.stderr index a99ce1b..8b13789 100644 --- a/examples/expected/0837-modules-array-const-no-cross-borrow.stderr +++ b/examples/expected/0837-modules-array-const-no-cross-borrow.stderr @@ -1,5 +1 @@ -error: unresolved 'K' (in examples/0837-modules-array-const-no-cross-borrow/h.sx fn use_k) - --> examples/0837-modules-array-const-no-cross-borrow/h.sx:2:22 - | - 2 | use_k :: () -> s64 { K[2] } - | ^ + diff --git a/examples/expected/0837-modules-array-const-no-cross-borrow.stdout b/examples/expected/0837-modules-array-const-no-cross-borrow.stdout index 8b13789..499a784 100644 --- a/examples/expected/0837-modules-array-const-no-cross-borrow.stdout +++ b/examples/expected/0837-modules-array-const-no-cross-borrow.stdout @@ -1 +1 @@ - +4 33 diff --git a/examples/expected/0903-optionals-optional-roundtrip.ir b/examples/expected/0903-optionals-optional-roundtrip.ir index aeb1ccc..4d6d67b 100644 --- a/examples/expected/0903-optionals-optional-roundtrip.ir +++ b/examples/expected/0903-optionals-optional-roundtrip.ir @@ -1,5 +1,5 @@ -@__sx_default_context = internal global { { ptr, ptr, ptr }, ptr } { { ptr, ptr, ptr } { ptr null, ptr @__thunk_CAllocator_Allocator_alloc, ptr @__thunk_CAllocator_Allocator_dealloc }, ptr null } +@__sx_default_context = internal constant { { ptr, ptr, ptr }, ptr } { { ptr, ptr, ptr } { ptr null, ptr @__thunk_CAllocator_Allocator_alloc, ptr @__thunk_CAllocator_Allocator_dealloc }, ptr null } @__Sizable__Widget__vtable = internal constant { ptr } { ptr @__thunk_Widget_Sizable_size } @str = private unnamed_addr constant [2 x i8] c"0\00", align 1 @str.125 = private unnamed_addr constant [2 x i8] c"0\00", align 1 diff --git a/examples/expected/0904-optionals-any-to-string-optional.ir b/examples/expected/0904-optionals-any-to-string-optional.ir index 26b9c55..5012d49 100644 --- a/examples/expected/0904-optionals-any-to-string-optional.ir +++ b/examples/expected/0904-optionals-any-to-string-optional.ir @@ -1,5 +1,5 @@ -@__sx_default_context = internal global { { ptr, ptr, ptr }, ptr } { { ptr, ptr, ptr } { ptr null, ptr @__thunk_CAllocator_Allocator_alloc, ptr @__thunk_CAllocator_Allocator_dealloc }, ptr null } +@__sx_default_context = internal constant { { ptr, ptr, ptr }, ptr } { { ptr, ptr, ptr } { ptr null, ptr @__thunk_CAllocator_Allocator_alloc, ptr @__thunk_CAllocator_Allocator_dealloc }, ptr null } @str = private unnamed_addr constant [2 x i8] c"0\00", align 1 @str.125 = private unnamed_addr constant [2 x i8] c"0\00", align 1 @str.126 = private unnamed_addr constant [5 x i8] c"true\00", align 1 diff --git a/examples/expected/1004-errors-try.ir b/examples/expected/1004-errors-try.ir index d6cbd27..a160723 100644 --- a/examples/expected/1004-errors-try.ir +++ b/examples/expected/1004-errors-try.ir @@ -1,5 +1,5 @@ -@__sx_default_context = internal global { { ptr, ptr, ptr }, ptr } { { ptr, ptr, ptr } { ptr null, ptr @__thunk_CAllocator_Allocator_alloc, ptr @__thunk_CAllocator_Allocator_dealloc }, ptr null } +@__sx_default_context = internal constant { { ptr, ptr, ptr }, ptr } { { ptr, ptr, ptr } { ptr null, ptr @__thunk_CAllocator_Allocator_alloc, ptr @__thunk_CAllocator_Allocator_dealloc }, ptr null } @str = private unnamed_addr constant [2 x i8] c"0\00", align 1 @str.125 = private unnamed_addr constant [2 x i8] c"0\00", align 1 @str.126 = private unnamed_addr constant [5 x i8] c"true\00", align 1 diff --git a/examples/expected/1006-errors-inferred-error-sets.ir b/examples/expected/1006-errors-inferred-error-sets.ir index a886900..47be9ed 100644 --- a/examples/expected/1006-errors-inferred-error-sets.ir +++ b/examples/expected/1006-errors-inferred-error-sets.ir @@ -1,5 +1,5 @@ -@__sx_default_context = internal global { { ptr, ptr, ptr }, ptr } { { ptr, ptr, ptr } { ptr null, ptr @__thunk_CAllocator_Allocator_alloc, ptr @__thunk_CAllocator_Allocator_dealloc }, ptr null } +@__sx_default_context = internal constant { { ptr, ptr, ptr }, ptr } { { ptr, ptr, ptr } { ptr null, ptr @__thunk_CAllocator_Allocator_alloc, ptr @__thunk_CAllocator_Allocator_dealloc }, ptr null } @str = private unnamed_addr constant [2 x i8] c"0\00", align 1 @str.126 = private unnamed_addr constant [2 x i8] c"0\00", align 1 @str.127 = private unnamed_addr constant [5 x i8] c"true\00", align 1 diff --git a/examples/expected/1009-errors-catch.ir b/examples/expected/1009-errors-catch.ir index 39e6abb..38e40be 100644 --- a/examples/expected/1009-errors-catch.ir +++ b/examples/expected/1009-errors-catch.ir @@ -1,5 +1,5 @@ -@__sx_default_context = internal global { { ptr, ptr, ptr }, ptr } { { ptr, ptr, ptr } { ptr null, ptr @__thunk_CAllocator_Allocator_alloc, ptr @__thunk_CAllocator_Allocator_dealloc }, ptr null } +@__sx_default_context = internal constant { { ptr, ptr, ptr }, ptr } { { ptr, ptr, ptr } { ptr null, ptr @__thunk_CAllocator_Allocator_alloc, ptr @__thunk_CAllocator_Allocator_dealloc }, ptr null } @str = private unnamed_addr constant [2 x i8] c"0\00", align 1 @str.125 = private unnamed_addr constant [2 x i8] c"0\00", align 1 @str.126 = private unnamed_addr constant [5 x i8] c"true\00", align 1 diff --git a/examples/expected/1159-diagnostics-array-const-mixed-elements.exit b/examples/expected/1159-diagnostics-array-const-mixed-elements.exit new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/examples/expected/1159-diagnostics-array-const-mixed-elements.exit @@ -0,0 +1 @@ +1 diff --git a/examples/expected/1159-diagnostics-array-const-mixed-elements.stderr b/examples/expected/1159-diagnostics-array-const-mixed-elements.stderr new file mode 100644 index 0000000..85229e1 --- /dev/null +++ b/examples/expected/1159-diagnostics-array-const-mixed-elements.stderr @@ -0,0 +1,11 @@ +error: constant 'BAD' mixes incompatible element types — annotate the array type + --> examples/1159-diagnostics-array-const-mixed-elements.sx:8:19 + | + 8 | BAD :: .["alpha", 1]; + | ^ + +error: unresolved 'BAD' (in examples/1159-diagnostics-array-const-mixed-elements.sx fn main) + --> examples/1159-diagnostics-array-const-mixed-elements.sx:11:19 + | +11 | print("{}\n", BAD[0]); + | ^^^ diff --git a/examples/expected/1159-diagnostics-array-const-mixed-elements.stdout b/examples/expected/1159-diagnostics-array-const-mixed-elements.stdout new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/examples/expected/1159-diagnostics-array-const-mixed-elements.stdout @@ -0,0 +1 @@ + diff --git a/examples/expected/1160-diagnostics-array-const-runtime-element.exit b/examples/expected/1160-diagnostics-array-const-runtime-element.exit new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/examples/expected/1160-diagnostics-array-const-runtime-element.exit @@ -0,0 +1 @@ +1 diff --git a/examples/expected/1160-diagnostics-array-const-runtime-element.stderr b/examples/expected/1160-diagnostics-array-const-runtime-element.stderr new file mode 100644 index 0000000..077ef76 --- /dev/null +++ b/examples/expected/1160-diagnostics-array-const-runtime-element.stderr @@ -0,0 +1,11 @@ +error: constant 'BAD' must be initialized by compile-time constant elements + --> examples/1160-diagnostics-array-const-runtime-element.sx:8:16 + | + 8 | BAD : [2]s64 : .[1, f()]; + | ^^^^^^^^^ + +error: unresolved 'BAD' (in examples/1160-diagnostics-array-const-runtime-element.sx fn main) + --> examples/1160-diagnostics-array-const-runtime-element.sx:11:19 + | +11 | print("{}\n", BAD[0]); + | ^^^ diff --git a/examples/expected/1160-diagnostics-array-const-runtime-element.stdout b/examples/expected/1160-diagnostics-array-const-runtime-element.stdout new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/examples/expected/1160-diagnostics-array-const-runtime-element.stdout @@ -0,0 +1 @@ + diff --git a/examples/expected/1161-diagnostics-array-const-dim-mismatch.exit b/examples/expected/1161-diagnostics-array-const-dim-mismatch.exit new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/examples/expected/1161-diagnostics-array-const-dim-mismatch.exit @@ -0,0 +1 @@ +1 diff --git a/examples/expected/1161-diagnostics-array-const-dim-mismatch.stderr b/examples/expected/1161-diagnostics-array-const-dim-mismatch.stderr new file mode 100644 index 0000000..68d258e --- /dev/null +++ b/examples/expected/1161-diagnostics-array-const-dim-mismatch.stderr @@ -0,0 +1,11 @@ +error: constant 'BAD' declares [3] elements but its initializer has 2 + --> examples/1161-diagnostics-array-const-dim-mismatch.sx:6:16 + | + 6 | BAD : [3]s64 : .[1, 2]; + | ^^^^^^^ + +error: unresolved 'BAD' (in examples/1161-diagnostics-array-const-dim-mismatch.sx fn main) + --> examples/1161-diagnostics-array-const-dim-mismatch.sx:9:19 + | + 9 | print("{}\n", BAD[0]); + | ^^^ diff --git a/examples/expected/1161-diagnostics-array-const-dim-mismatch.stdout b/examples/expected/1161-diagnostics-array-const-dim-mismatch.stdout new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/examples/expected/1161-diagnostics-array-const-dim-mismatch.stdout @@ -0,0 +1 @@ + diff --git a/examples/expected/1202-ffi-cc-c-large-aggregate.ir b/examples/expected/1202-ffi-cc-c-large-aggregate.ir index 4c0e340..59b6fc0 100644 --- a/examples/expected/1202-ffi-cc-c-large-aggregate.ir +++ b/examples/expected/1202-ffi-cc-c-large-aggregate.ir @@ -1,5 +1,5 @@ -@__sx_default_context = internal global { { ptr, ptr, ptr }, ptr } { { ptr, ptr, ptr } { ptr null, ptr @__thunk_CAllocator_Allocator_alloc, ptr @__thunk_CAllocator_Allocator_dealloc }, ptr null } +@__sx_default_context = internal constant { { ptr, ptr, ptr }, ptr } { { ptr, ptr, ptr } { ptr null, ptr @__thunk_CAllocator_Allocator_alloc, ptr @__thunk_CAllocator_Allocator_dealloc }, ptr null } ; Function Attrs: nounwind declare void @out(ptr) #0 diff --git a/examples/expected/1309-ffi-objc-class-method-lowering.ir b/examples/expected/1309-ffi-objc-class-method-lowering.ir index 0c47d8e..fcbf784 100644 --- a/examples/expected/1309-ffi-objc-class-method-lowering.ir +++ b/examples/expected/1309-ffi-objc-class-method-lowering.ir @@ -1,8 +1,8 @@ @__SxFoo_state_ivar = internal global ptr null @__SxFoo_class = internal global ptr null -@__sx_default_context = internal global { { ptr, ptr, ptr }, ptr } { { ptr, ptr, ptr } { ptr null, ptr @__thunk_CAllocator_Allocator_alloc, ptr @__thunk_CAllocator_Allocator_dealloc }, ptr null } -@__sx_objc_cstr_dealloc = internal global [8 x i8] c"dealloc\00" +@__sx_default_context = internal constant { { ptr, ptr, ptr }, ptr } { { ptr, ptr, ptr } { ptr null, ptr @__thunk_CAllocator_Allocator_alloc, ptr @__thunk_CAllocator_Allocator_dealloc }, ptr null } +@__sx_objc_cstr_dealloc = internal constant [8 x i8] c"dealloc\00" @str = private unnamed_addr constant [2 x i8] c"0\00", align 1 @str.162 = private unnamed_addr constant [15 x i8] c"result := \22\22; \00", align 1 @str.163 = private unnamed_addr constant [37 x i8] c"result = concat(result, substr(fmt, \00", align 1 diff --git a/examples/expected/1314-ffi-objc-class-dealloc-roundtrip.ir b/examples/expected/1314-ffi-objc-class-dealloc-roundtrip.ir index 5bc4bb9..fe740bd 100644 --- a/examples/expected/1314-ffi-objc-class-dealloc-roundtrip.ir +++ b/examples/expected/1314-ffi-objc-class-dealloc-roundtrip.ir @@ -1,8 +1,8 @@ @__SxFoo_state_ivar = internal global ptr null @__SxFoo_class = internal global ptr null -@__sx_default_context = internal global { { ptr, ptr, ptr }, ptr } { { ptr, ptr, ptr } { ptr null, ptr @__thunk_CAllocator_Allocator_alloc, ptr @__thunk_CAllocator_Allocator_dealloc }, ptr null } -@__sx_objc_cstr_dealloc = internal global [8 x i8] c"dealloc\00" +@__sx_default_context = internal constant { { ptr, ptr, ptr }, ptr } { { ptr, ptr, ptr } { ptr null, ptr @__thunk_CAllocator_Allocator_alloc, ptr @__thunk_CAllocator_Allocator_dealloc }, ptr null } +@__sx_objc_cstr_dealloc = internal constant [8 x i8] c"dealloc\00" @str = private unnamed_addr constant [2 x i8] c"0\00", align 1 @str.162 = private unnamed_addr constant [15 x i8] c"result := \22\22; \00", align 1 @str.163 = private unnamed_addr constant [37 x i8] c"result = concat(result, substr(fmt, \00", align 1 diff --git a/examples/expected/1319-ffi-objc-property-sx-defined.ir b/examples/expected/1319-ffi-objc-property-sx-defined.ir index 2ec53af..274666e 100644 --- a/examples/expected/1319-ffi-objc-property-sx-defined.ir +++ b/examples/expected/1319-ffi-objc-property-sx-defined.ir @@ -1,7 +1,7 @@ @__SxBox_state_ivar = internal global ptr null @__SxBox_class = internal global ptr null -@__sx_default_context = internal global { { ptr, ptr, ptr }, ptr } { { ptr, ptr, ptr } { ptr null, ptr @__thunk_CAllocator_Allocator_alloc, ptr @__thunk_CAllocator_Allocator_dealloc }, ptr null } +@__sx_default_context = internal constant { { ptr, ptr, ptr }, ptr } { { ptr, ptr, ptr } { ptr null, ptr @__thunk_CAllocator_Allocator_alloc, ptr @__thunk_CAllocator_Allocator_dealloc }, ptr null } @OBJC_CLASSLIST_REFERENCES_SxBox = internal global ptr null @OBJC_SELECTOR_REFERENCES_init = internal global ptr null @OBJC_SELECTOR_REFERENCES_setWidth_ = internal global ptr null @@ -9,7 +9,7 @@ @OBJC_SELECTOR_REFERENCES_width = internal global ptr null @OBJC_SELECTOR_REFERENCES_height = internal global ptr null @OBJC_SELECTOR_REFERENCES_area = internal global ptr null -@__sx_objc_cstr_dealloc = internal global [8 x i8] c"dealloc\00" +@__sx_objc_cstr_dealloc = internal constant [8 x i8] c"dealloc\00" @str = private unnamed_addr constant [2 x i8] c"0\00", align 1 @str.162 = private unnamed_addr constant [2 x i8] c"0\00", align 1 @str.163 = private unnamed_addr constant [5 x i8] c"true\00", align 1 diff --git a/examples/expected/1329-ffi-objc-call-03-selector-sharing.ir b/examples/expected/1329-ffi-objc-call-03-selector-sharing.ir index 8f53d49..c5951de 100644 --- a/examples/expected/1329-ffi-objc-call-03-selector-sharing.ir +++ b/examples/expected/1329-ffi-objc-call-03-selector-sharing.ir @@ -1,5 +1,5 @@ -@__sx_default_context = internal global { { ptr, ptr, ptr }, ptr } { { ptr, ptr, ptr } { ptr null, ptr @__thunk_CAllocator_Allocator_alloc, ptr @__thunk_CAllocator_Allocator_dealloc }, ptr null } +@__sx_default_context = internal constant { { ptr, ptr, ptr }, ptr } { { ptr, ptr, ptr } { ptr null, ptr @__thunk_CAllocator_Allocator_alloc, ptr @__thunk_CAllocator_Allocator_dealloc }, ptr null } @OBJC_SELECTOR_REFERENCES_init = internal global ptr null @OBJC_SELECTOR_REFERENCES_release = internal global ptr null @str = private unnamed_addr constant [2 x i8] c"0\00", align 1 diff --git a/examples/expected/1332-ffi-objc-call-06-sret-return.ir b/examples/expected/1332-ffi-objc-call-06-sret-return.ir index 44d8595..b14f68d 100644 --- a/examples/expected/1332-ffi-objc-call-06-sret-return.ir +++ b/examples/expected/1332-ffi-objc-call-06-sret-return.ir @@ -1,5 +1,5 @@ -@__sx_default_context = internal global { { ptr, ptr, ptr }, ptr } { { ptr, ptr, ptr } { ptr null, ptr @__thunk_CAllocator_Allocator_alloc, ptr @__thunk_CAllocator_Allocator_dealloc }, ptr null } +@__sx_default_context = internal constant { { ptr, ptr, ptr }, ptr } { { ptr, ptr, ptr } { ptr null, ptr @__thunk_CAllocator_Allocator_alloc, ptr @__thunk_CAllocator_Allocator_dealloc }, ptr null } @OBJC_SELECTOR_REFERENCES_tripleValue = internal global ptr null @str = private unnamed_addr constant [2 x i8] c"0\00", align 1 @str.162 = private unnamed_addr constant [2 x i8] c"0\00", align 1 diff --git a/examples/expected/1347-ffi-objc-dsl-07-mangling-table.ir b/examples/expected/1347-ffi-objc-dsl-07-mangling-table.ir index 7340857..c97f945 100644 --- a/examples/expected/1347-ffi-objc-dsl-07-mangling-table.ir +++ b/examples/expected/1347-ffi-objc-dsl-07-mangling-table.ir @@ -1,5 +1,5 @@ -@__sx_default_context = internal global { { ptr, ptr, ptr }, ptr } { { ptr, ptr, ptr } { ptr null, ptr @__thunk_CAllocator_Allocator_alloc, ptr @__thunk_CAllocator_Allocator_dealloc }, ptr null } +@__sx_default_context = internal constant { { ptr, ptr, ptr }, ptr } { { ptr, ptr, ptr } { ptr null, ptr @__thunk_CAllocator_Allocator_alloc, ptr @__thunk_CAllocator_Allocator_dealloc }, ptr null } @OBJC_SELECTOR_REFERENCES_length = internal global ptr null @OBJC_SELECTOR_REFERENCES_addObject_ = internal global ptr null @OBJC_SELECTOR_REFERENCES_combine_and_ = internal global ptr null diff --git a/examples/expected/1402-ffi-jni-call-03-methodid-sharing.ir b/examples/expected/1402-ffi-jni-call-03-methodid-sharing.ir index 99c2e69..fbbafbf 100644 --- a/examples/expected/1402-ffi-jni-call-03-methodid-sharing.ir +++ b/examples/expected/1402-ffi-jni-call-03-methodid-sharing.ir @@ -1,6 +1,6 @@ @g_should_call = internal global i1 false -@__sx_default_context = internal global { { ptr, ptr, ptr }, ptr } { { ptr, ptr, ptr } { ptr null, ptr @__thunk_CAllocator_Allocator_alloc, ptr @__thunk_CAllocator_Allocator_dealloc }, ptr null } +@__sx_default_context = internal constant { { ptr, ptr, ptr }, ptr } { { ptr, ptr, ptr } { ptr null, ptr @__thunk_CAllocator_Allocator_alloc, ptr @__thunk_CAllocator_Allocator_dealloc }, ptr null } @str = private unnamed_addr constant [2 x i8] c"0\00", align 1 @str.125 = private unnamed_addr constant [15 x i8] c"result := \22\22; \00", align 1 @str.126 = private unnamed_addr constant [37 x i8] c"result = concat(result, substr(fmt, \00", align 1 diff --git a/examples/expected/1403-ffi-jni-call-04-jint-return.ir b/examples/expected/1403-ffi-jni-call-04-jint-return.ir index 908ca10..5618213 100644 --- a/examples/expected/1403-ffi-jni-call-04-jint-return.ir +++ b/examples/expected/1403-ffi-jni-call-04-jint-return.ir @@ -1,6 +1,6 @@ @g_should_call = internal global i1 false -@__sx_default_context = internal global { { ptr, ptr, ptr }, ptr } { { ptr, ptr, ptr } { ptr null, ptr @__thunk_CAllocator_Allocator_alloc, ptr @__thunk_CAllocator_Allocator_dealloc }, ptr null } +@__sx_default_context = internal constant { { ptr, ptr, ptr }, ptr } { { ptr, ptr, ptr } { ptr null, ptr @__thunk_CAllocator_Allocator_alloc, ptr @__thunk_CAllocator_Allocator_dealloc }, ptr null } @str = private unnamed_addr constant [2 x i8] c"0\00", align 1 @str.125 = private unnamed_addr constant [15 x i8] c"result := \22\22; \00", align 1 @str.126 = private unnamed_addr constant [37 x i8] c"result = concat(result, substr(fmt, \00", align 1 diff --git a/examples/expected/1404-ffi-jni-call-05-jlong-return.ir b/examples/expected/1404-ffi-jni-call-05-jlong-return.ir index 016c7ba..88efaae 100644 --- a/examples/expected/1404-ffi-jni-call-05-jlong-return.ir +++ b/examples/expected/1404-ffi-jni-call-05-jlong-return.ir @@ -1,6 +1,6 @@ @g_should_call = internal global i1 false -@__sx_default_context = internal global { { ptr, ptr, ptr }, ptr } { { ptr, ptr, ptr } { ptr null, ptr @__thunk_CAllocator_Allocator_alloc, ptr @__thunk_CAllocator_Allocator_dealloc }, ptr null } +@__sx_default_context = internal constant { { ptr, ptr, ptr }, ptr } { { ptr, ptr, ptr } { ptr null, ptr @__thunk_CAllocator_Allocator_alloc, ptr @__thunk_CAllocator_Allocator_dealloc }, ptr null } @str = private unnamed_addr constant [2 x i8] c"0\00", align 1 @str.125 = private unnamed_addr constant [15 x i8] c"result := \22\22; \00", align 1 @str.126 = private unnamed_addr constant [37 x i8] c"result = concat(result, substr(fmt, \00", align 1 diff --git a/examples/expected/1405-ffi-jni-call-06-jdouble-return.ir b/examples/expected/1405-ffi-jni-call-06-jdouble-return.ir index cb72757..dc7f2e0 100644 --- a/examples/expected/1405-ffi-jni-call-06-jdouble-return.ir +++ b/examples/expected/1405-ffi-jni-call-06-jdouble-return.ir @@ -1,6 +1,6 @@ @g_should_call = internal global i1 false -@__sx_default_context = internal global { { ptr, ptr, ptr }, ptr } { { ptr, ptr, ptr } { ptr null, ptr @__thunk_CAllocator_Allocator_alloc, ptr @__thunk_CAllocator_Allocator_dealloc }, ptr null } +@__sx_default_context = internal constant { { ptr, ptr, ptr }, ptr } { { ptr, ptr, ptr } { ptr null, ptr @__thunk_CAllocator_Allocator_alloc, ptr @__thunk_CAllocator_Allocator_dealloc }, ptr null } @str = private unnamed_addr constant [2 x i8] c"0\00", align 1 @str.125 = private unnamed_addr constant [15 x i8] c"result := \22\22; \00", align 1 @str.126 = private unnamed_addr constant [37 x i8] c"result = concat(result, substr(fmt, \00", align 1 diff --git a/examples/expected/1406-ffi-jni-call-07-jboolean-return.ir b/examples/expected/1406-ffi-jni-call-07-jboolean-return.ir index 0267a3e..3293d80 100644 --- a/examples/expected/1406-ffi-jni-call-07-jboolean-return.ir +++ b/examples/expected/1406-ffi-jni-call-07-jboolean-return.ir @@ -1,6 +1,6 @@ @g_should_call = internal global i1 false -@__sx_default_context = internal global { { ptr, ptr, ptr }, ptr } { { ptr, ptr, ptr } { ptr null, ptr @__thunk_CAllocator_Allocator_alloc, ptr @__thunk_CAllocator_Allocator_dealloc }, ptr null } +@__sx_default_context = internal constant { { ptr, ptr, ptr }, ptr } { { ptr, ptr, ptr } { ptr null, ptr @__thunk_CAllocator_Allocator_alloc, ptr @__thunk_CAllocator_Allocator_dealloc }, ptr null } @str = private unnamed_addr constant [2 x i8] c"0\00", align 1 @str.125 = private unnamed_addr constant [15 x i8] c"result := \22\22; \00", align 1 @str.126 = private unnamed_addr constant [37 x i8] c"result = concat(result, substr(fmt, \00", align 1 diff --git a/examples/expected/1407-ffi-jni-call-08-jobject-return.ir b/examples/expected/1407-ffi-jni-call-08-jobject-return.ir index 0e866d3..38e1334 100644 --- a/examples/expected/1407-ffi-jni-call-08-jobject-return.ir +++ b/examples/expected/1407-ffi-jni-call-08-jobject-return.ir @@ -1,6 +1,6 @@ @g_should_call = internal global i1 false -@__sx_default_context = internal global { { ptr, ptr, ptr }, ptr } { { ptr, ptr, ptr } { ptr null, ptr @__thunk_CAllocator_Allocator_alloc, ptr @__thunk_CAllocator_Allocator_dealloc }, ptr null } +@__sx_default_context = internal constant { { ptr, ptr, ptr }, ptr } { { ptr, ptr, ptr } { ptr null, ptr @__thunk_CAllocator_Allocator_alloc, ptr @__thunk_CAllocator_Allocator_dealloc }, ptr null } @str = private unnamed_addr constant [2 x i8] c"0\00", align 1 @str.125 = private unnamed_addr constant [15 x i8] c"result := \22\22; \00", align 1 @str.126 = private unnamed_addr constant [37 x i8] c"result = concat(result, substr(fmt, \00", align 1 diff --git a/examples/expected/1408-ffi-jni-call-09-static.ir b/examples/expected/1408-ffi-jni-call-09-static.ir index a738cc9..2493719 100644 --- a/examples/expected/1408-ffi-jni-call-09-static.ir +++ b/examples/expected/1408-ffi-jni-call-09-static.ir @@ -1,6 +1,6 @@ @g_should_call = internal global i1 false -@__sx_default_context = internal global { { ptr, ptr, ptr }, ptr } { { ptr, ptr, ptr } { ptr null, ptr @__thunk_CAllocator_Allocator_alloc, ptr @__thunk_CAllocator_Allocator_dealloc }, ptr null } +@__sx_default_context = internal constant { { ptr, ptr, ptr }, ptr } { { ptr, ptr, ptr } { ptr null, ptr @__thunk_CAllocator_Allocator_alloc, ptr @__thunk_CAllocator_Allocator_dealloc }, ptr null } @str = private unnamed_addr constant [2 x i8] c"0\00", align 1 @str.125 = private unnamed_addr constant [15 x i8] c"result := \22\22; \00", align 1 @str.126 = private unnamed_addr constant [37 x i8] c"result = concat(result, substr(fmt, \00", align 1 diff --git a/examples/expected/1418-ffi-jni-class-08-call.ir b/examples/expected/1418-ffi-jni-class-08-call.ir index cc3217d..88a65ef 100644 --- a/examples/expected/1418-ffi-jni-class-08-call.ir +++ b/examples/expected/1418-ffi-jni-class-08-call.ir @@ -1,6 +1,6 @@ @g_should_call = internal global i1 false -@__sx_default_context = internal global { { ptr, ptr, ptr }, ptr } { { ptr, ptr, ptr } { ptr null, ptr @__thunk_CAllocator_Allocator_alloc, ptr @__thunk_CAllocator_Allocator_dealloc }, ptr null } +@__sx_default_context = internal constant { { ptr, ptr, ptr }, ptr } { { ptr, ptr, ptr } { ptr null, ptr @__thunk_CAllocator_Allocator_alloc, ptr @__thunk_CAllocator_Allocator_dealloc }, ptr null } @str = private unnamed_addr constant [2 x i8] c"0\00", align 1 @str.125 = private unnamed_addr constant [15 x i8] c"result := \22\22; \00", align 1 @str.126 = private unnamed_addr constant [37 x i8] c"result = concat(result, substr(fmt, \00", align 1 diff --git a/examples/expected/1421-ffi-jni-env-02-lexical-direct.ir b/examples/expected/1421-ffi-jni-env-02-lexical-direct.ir index ef9f689..4884c2a 100644 --- a/examples/expected/1421-ffi-jni-env-02-lexical-direct.ir +++ b/examples/expected/1421-ffi-jni-env-02-lexical-direct.ir @@ -1,6 +1,6 @@ @g_should_call = internal global i1 false -@__sx_default_context = internal global { { ptr, ptr, ptr }, ptr } { { ptr, ptr, ptr } { ptr null, ptr @__thunk_CAllocator_Allocator_alloc, ptr @__thunk_CAllocator_Allocator_dealloc }, ptr null } +@__sx_default_context = internal constant { { ptr, ptr, ptr }, ptr } { { ptr, ptr, ptr } { ptr null, ptr @__thunk_CAllocator_Allocator_alloc, ptr @__thunk_CAllocator_Allocator_dealloc }, ptr null } @str = private unnamed_addr constant [2 x i8] c"0\00", align 1 @str.125 = private unnamed_addr constant [15 x i8] c"result := \22\22; \00", align 1 @str.126 = private unnamed_addr constant [37 x i8] c"result = concat(result, substr(fmt, \00", align 1 diff --git a/examples/expected/1425-ffi-jni-main-03-ctor.ir b/examples/expected/1425-ffi-jni-main-03-ctor.ir index eec5be6..3812d9f 100644 --- a/examples/expected/1425-ffi-jni-main-03-ctor.ir +++ b/examples/expected/1425-ffi-jni-main-03-ctor.ir @@ -1,6 +1,6 @@ @g_held_view = internal global ptr null -@__sx_default_context = internal global { { ptr, ptr, ptr }, ptr } { { ptr, ptr, ptr } { ptr null, ptr @__thunk_CAllocator_Allocator_alloc, ptr @__thunk_CAllocator_Allocator_dealloc }, ptr null } +@__sx_default_context = internal constant { { ptr, ptr, ptr }, ptr } { { ptr, ptr, ptr } { ptr null, ptr @__thunk_CAllocator_Allocator_alloc, ptr @__thunk_CAllocator_Allocator_dealloc }, ptr null } @str = private unnamed_addr constant [9 x i8] c"onCreate\00", align 1 @str.162 = private unnamed_addr constant [23 x i8] c"(Landroid/os/Bundle;)V\00", align 1 @jni.parent.path = private unnamed_addr constant [21 x i8] c"android/app/Activity\00", align 1 diff --git a/src/ir/emit_llvm.zig b/src/ir/emit_llvm.zig index 9937725..193c99f 100644 --- a/src/ir/emit_llvm.zig +++ b/src/ir/emit_llvm.zig @@ -962,6 +962,8 @@ pub const LLVMEmitter = struct { c.LLVMSetInitializer(llvm_global, c.LLVMConstNull(llvm_ty)); } + if (global.is_const) c.LLVMSetGlobalConstant(llvm_global, 1); + self.global_map.put(@intCast(i), llvm_global) catch {}; } } diff --git a/src/ir/lower.zig b/src/ir/lower.zig index ff29cf6..0c2999a 100644 --- a/src/ir/lower.zig +++ b/src/ir/lower.zig @@ -1587,6 +1587,8 @@ pub const Lowering = struct { pub const fnPtrTypeWantsCtx = lower_decl.fnPtrTypeWantsCtx; pub const scanDecls = lower_decl.scanDecls; pub const registerTypedModuleConst = lower_decl.registerTypedModuleConst; + pub const registerConstArrayGlobal = lower_decl.registerConstArrayGlobal; + pub const inferConstArrayType = lower_decl.inferConstArrayType; pub const typedConstInitFits = lower_decl.typedConstInitFits; pub const constExprInitFits = lower_decl.constExprInitFits; pub const registerTopLevelGlobal = lower_decl.registerTopLevelGlobal; diff --git a/src/ir/lower/comptime.zig b/src/ir/lower/comptime.zig index 80e2c1c..61afc3b 100644 --- a/src/ir/lower/comptime.zig +++ b/src/ir/lower/comptime.zig @@ -50,7 +50,12 @@ pub fn constArrayLiteral(self: *Lowering, elements: []const *const Node, array_t /// expression is not constant-foldable here. pub fn constExprValue(self: *Lowering, expr: *const Node, expected_ty: TypeId) ?inst_mod.ConstantValue { return switch (expr.data) { - .int_literal => |il| .{ .int = il.value }, + // An int element in a FLOAT destination converts exactly (the + // int+float promotion rule, element-wise — `[2]f64 : .[1, 2.5]`). + .int_literal => |il| if (isFloat(expected_ty)) + .{ .float = @floatFromInt(il.value) } + else + .{ .int = il.value }, .bool_literal => |bl| .{ .boolean = bl.value }, // A float into an INTEGER destination follows the implicit // narrowing rule: an integral float folds to its int, a @@ -71,7 +76,10 @@ pub fn constExprValue(self: *Lowering, expr: *const Node, expected_ty: TypeId) ? .null_literal => .null_val, .unary_op => |uo| switch (uo.op) { .negate => switch (uo.operand.data) { - .int_literal => |il| .{ .int = -il.value }, + .int_literal => |il| if (isFloat(expected_ty)) + .{ .float = @floatFromInt(-il.value) } + else + .{ .int = -il.value }, .float_literal => |fl| .{ .float = -fl.value }, else => null, }, diff --git a/src/ir/lower/decl.zig b/src/ir/lower/decl.zig index c843c80..229d29f 100644 --- a/src/ir/lower/decl.zig +++ b/src/ir/lower/decl.zig @@ -778,7 +778,10 @@ pub fn scanDecls(self: *Lowering, decls: []const *const Node) void { self.setCurrentSourceFile(decl.source_file); switch (decl.data) { .var_decl => self.registerTopLevelGlobal(&decl.data.var_decl), - .const_decl => |cd| self.registerTypedModuleConst(&cd), + .const_decl => |cd| if (cd.value.data == .array_literal) + self.registerConstArrayGlobal(&cd) + else + self.registerTypedModuleConst(&cd), else => {}, } } @@ -924,6 +927,95 @@ pub fn constExprInitFits(self: *Lowering, init_ty: TypeId, dst_ty: TypeId) bool return init_ty == dst_ty; } +/// Register an array-typed `::` constant (`K : [4]s64 : .[...]`, or the +/// untyped `A :: .[1, 2, 3]`) as an IMMUTABLE module global: one storage, +/// reads GEP it, the emitter marks it LLVMSetGlobalConstant, dead-global +/// elimination drops it when unused. Source-aware reads come for free via +/// `selectGlobalAuthor` (the per-source partition is written here). +pub fn registerConstArrayGlobal(self: *Lowering, cd: *const ast.ConstDecl) void { + const al = &cd.value.data.array_literal; + const arr_ty: TypeId = blk: { + if (cd.type_annotation) |ta| { + const t = self.resolveType(ta); + if (t == .unresolved) return; // annotation already diagnosed + if (t.isBuiltin() or self.module.types.get(t) != .array) { + if (self.diagnostics) |d| + d.addFmt(.err, cd.value.span, "constant '{s}' has an array-literal initializer but its annotation is not an array type", .{cd.name}); + return; + } + const dim = self.module.types.get(t).array.length; + if (dim != al.elements.len) { + if (self.diagnostics) |d| + d.addFmt(.err, cd.value.span, "constant '{s}' declares [{d}] elements but its initializer has {d}", .{ cd.name, dim, al.elements.len }); + return; + } + break :blk t; + } + break :blk self.inferConstArrayType(cd.name, al.elements, cd.value.span) orelse return; + }; + const init_val = self.constArrayLiteral(al.elements, arr_ty) orelse { + if (self.diagnostics) |d| + d.addFmt(.err, cd.value.span, "constant '{s}' must be initialized by compile-time constant elements", .{cd.name}); + return; + }; + const name_id = self.module.types.internString(cd.name); + const gid = self.module.addGlobal(.{ + .name = name_id, + .ty = arr_ty, + .init_val = init_val, + .is_const = true, + }); + self.putGlobal(self.current_source_file, cd.name, .{ .id = gid, .ty = arr_ty }); +} + +/// Infer `[N]T` for an untyped array-literal constant. Element types unify: +/// all ints → s64; ANY float promotes the element type to f64 (ints convert +/// exactly — the int+float promotion rule for consts, element-wise); bool / +/// string homogeneous only. A non-numeric mix or a non-inferable element +/// shape (nested aggregate, enum literal, named const) asks for an +/// annotation rather than guessing. +pub fn inferConstArrayType(self: *Lowering, name: []const u8, elements: []const *const Node, span: ast.Span) ?TypeId { + if (elements.len == 0) { + if (self.diagnostics) |d| + d.addFmt(.err, span, "constant '{s}' is an empty array literal — annotate the type (e.g. `{s} : [0]s64 : .[]`)", .{ name, name }); + return null; + } + var elem_ty: ?TypeId = null; + for (elements) |e| { + const leaf: ?TypeId = switch (e.data) { + .int_literal => .s64, + .float_literal => .f64, + .bool_literal => .bool, + .string_literal => .string, + .unary_op => |uo| if (uo.op == .negate) switch (uo.operand.data) { + .int_literal => .s64, + .float_literal => .f64, + else => null, + } else null, + else => null, + }; + const lt = leaf orelse { + if (self.diagnostics) |d| + d.addFmt(.err, e.span, "cannot infer the element type of constant '{s}' from this element — annotate the array type", .{name}); + return null; + }; + if (elem_ty) |prev| { + if (prev == lt) continue; + // Numeric mix promotes to the float element type. + const numeric_pair = (prev == .s64 and lt == .f64) or (prev == .f64 and lt == .s64); + if (numeric_pair) { + elem_ty = .f64; + continue; + } + if (self.diagnostics) |d| + d.addFmt(.err, e.span, "constant '{s}' mixes incompatible element types — annotate the array type", .{name}); + return null; + } + elem_ty = lt; + } + return self.module.types.arrayOf(elem_ty.?, @intCast(elements.len)); +} + /// Register a top-level mutable global (e.g., `context : Context = ---;`). /// Run AFTER `resolveForwardIdentifierAliases` so a forward identifier alias /// in the type annotation (`A :: B; B :: s32; g : A = 7;`) resolves to its