lang: array-typed '::' consts as immutable globals (PLAN-CONST-AGG step 1)

K : [4]s64 : .[...] and the untyped A :: .[1, 2, 3] register as
is_const globals: one storage, reads GEP it, dead-global elimination
drops unused ones, source-aware reads come free via selectGlobalAuthor.

- registerConstArrayGlobal (scanDecls pass 2): typed via the annotation
  (array-ness + dimension/count checked), untyped via element-type
  unification — all ints s64; ANY float promotes the element type to
  f64 with ints converting exactly; bool/string homogeneous; a
  non-numeric mix or non-inferable element asks for an annotation.
- constExprValue converts int elements into float destinations exactly
  (the int+float promotion rule, element-wise).
- emitGlobals marks is_const globals LLVMSetGlobalConstant — also flips
  the comptime-backed #run globals and __sx_default_context to
  'constant' (37 pinned IR snapshots regenerated; runtime unchanged).
- Element shapes: nested arrays, struct elements, strings, bools.
  Non-constant elements / dim mismatch / mixed types diagnose loudly.

Examples: 0177 (feature matrix incl. @K reads through *[4]s64 — needs
the 0117 fix), 1159/1160/1161 (diagnostics), 0837 repointed to values.
This commit is contained in:
agra
2026-06-11 12:26:26 +03:00
parent 82d6b8da0e
commit 8908e78943
61 changed files with 273 additions and 58 deletions

View File

@@ -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]);
}

View File

@@ -1,11 +1,11 @@
// An ARRAY-typed `::` const (`K : [4]s64 : .[...]`) is not a supported // An ARRAY-typed `::` const is an immutable global owned by its module.
// module-const shape — its own module's read diagnoses cleanly as // Cross-module: the main file's scalar `K : s64 : 4` and h.sx's array
// unresolved. The own author OWNS the name: the read must never borrow // `K : [4]s64 : .[...]` coexist — each module's bare `K` binds its OWN
// another module's same-named scalar const (which used to type `K[2]` // author (h's use_k reads ITS array, main's K stays the scalar 4).
// against the scalar and panic at LLVM emission).
// //
// Regression (issue 0115). When array `::` consts land, repoint this // Regression (issue 0115): h.sx's read used to borrow main's scalar K
// example at the new behavior. // 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"; #import "modules/std.sx";
h :: #import "0837-modules-array-const-no-cross-borrow/h.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; K : s64 : 4;
main :: () { main :: () {
print("{}\n", h.use_k()); print("{} {}\n", K, h.use_k());
} }

View File

@@ -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]);
}

View File

@@ -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]);
}

View File

@@ -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]);
}

View File

@@ -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 = 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.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 @str.466 = private unnamed_addr constant [5 x i8] c"true\00", align 1

View File

@@ -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 = 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.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 @str.466 = private unnamed_addr constant [5 x i8] c"true\00", align 1

View File

@@ -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 = 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.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 @str.126 = private unnamed_addr constant [5 x i8] c"true\00", align 1

View File

@@ -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 = 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.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 @str.126 = private unnamed_addr constant [5 x i8] c"true\00", align 1

View File

@@ -0,0 +1 @@
0

View File

@@ -0,0 +1 @@

View File

@@ -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

View File

@@ -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 = 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.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 @str.126 = private unnamed_addr constant [5 x i8] c"true\00", align 1

View File

@@ -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 = 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.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 @str.126 = private unnamed_addr constant [5 x i8] c"true\00", align 1

View File

@@ -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 = 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.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 @str.126 = private unnamed_addr constant [5 x i8] c"true\00", align 1

View File

@@ -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 = 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.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 @str.126 = private unnamed_addr constant [5 x i8] c"true\00", align 1

View File

@@ -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__IntCell__vtable = internal constant { ptr } { ptr @__thunk_IntCell_VL__s64_get }
@__VL__string__StrCell__vtable = internal constant { ptr } { ptr @__thunk_StrCell_VL__string_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 @str = private unnamed_addr constant [2 x i8] c"0\00", align 1

View File

@@ -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__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 } @__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 @str = private unnamed_addr constant [2 x i8] c"0\00", align 1

View File

@@ -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 } @__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 = 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 @str.466 = private unnamed_addr constant [2 x i8] c"0\00", align 1

View File

@@ -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 = 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.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 @str.126 = private unnamed_addr constant [5 x i8] c"true\00", align 1

View File

@@ -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 = 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.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 @str.126 = private unnamed_addr constant [5 x i8] c"true\00", align 1

View File

@@ -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 = 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.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 @str.126 = private unnamed_addr constant [5 x i8] c"true\00", align 1

View File

@@ -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 = 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.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 @str.126 = private unnamed_addr constant [5 x i8] c"true\00", align 1

View File

@@ -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] }
| ^

View File

@@ -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 } @__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 = 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.125 = private unnamed_addr constant [2 x i8] c"0\00", align 1

View File

@@ -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 = 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.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 @str.126 = private unnamed_addr constant [5 x i8] c"true\00", align 1

View File

@@ -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 = 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.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 @str.126 = private unnamed_addr constant [5 x i8] c"true\00", align 1

View File

@@ -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 = 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.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 @str.127 = private unnamed_addr constant [5 x i8] c"true\00", align 1

View File

@@ -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 = 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.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 @str.126 = private unnamed_addr constant [5 x i8] c"true\00", align 1

View File

@@ -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]);
| ^^^

View File

@@ -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]);
| ^^^

View File

@@ -0,0 +1 @@
1

View File

@@ -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]);
| ^^^

View File

@@ -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 ; Function Attrs: nounwind
declare void @out(ptr) #0 declare void @out(ptr) #0

View File

@@ -1,8 +1,8 @@
@__SxFoo_state_ivar = internal global ptr null @__SxFoo_state_ivar = internal global ptr null
@__SxFoo_class = 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_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 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 = 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.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 @str.163 = private unnamed_addr constant [37 x i8] c"result = concat(result, substr(fmt, \00", align 1

View File

@@ -1,8 +1,8 @@
@__SxFoo_state_ivar = internal global ptr null @__SxFoo_state_ivar = internal global ptr null
@__SxFoo_class = 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_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 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 = 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.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 @str.163 = private unnamed_addr constant [37 x i8] c"result = concat(result, substr(fmt, \00", align 1

View File

@@ -1,7 +1,7 @@
@__SxBox_state_ivar = internal global ptr null @__SxBox_state_ivar = internal global ptr null
@__SxBox_class = 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_CLASSLIST_REFERENCES_SxBox = internal global ptr null
@OBJC_SELECTOR_REFERENCES_init = internal global ptr null @OBJC_SELECTOR_REFERENCES_init = internal global ptr null
@OBJC_SELECTOR_REFERENCES_setWidth_ = 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_width = internal global ptr null
@OBJC_SELECTOR_REFERENCES_height = internal global ptr null @OBJC_SELECTOR_REFERENCES_height = internal global ptr null
@OBJC_SELECTOR_REFERENCES_area = 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 = 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.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 @str.163 = private unnamed_addr constant [5 x i8] c"true\00", align 1

View File

@@ -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_init = internal global ptr null
@OBJC_SELECTOR_REFERENCES_release = 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 @str = private unnamed_addr constant [2 x i8] c"0\00", align 1

View File

@@ -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 @OBJC_SELECTOR_REFERENCES_tripleValue = internal global ptr null
@str = private unnamed_addr constant [2 x i8] c"0\00", align 1 @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.162 = private unnamed_addr constant [2 x i8] c"0\00", align 1

View File

@@ -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_length = internal global ptr null
@OBJC_SELECTOR_REFERENCES_addObject_ = internal global ptr null @OBJC_SELECTOR_REFERENCES_addObject_ = internal global ptr null
@OBJC_SELECTOR_REFERENCES_combine_and_ = internal global ptr null @OBJC_SELECTOR_REFERENCES_combine_and_ = internal global ptr null

View File

@@ -1,6 +1,6 @@
@g_should_call = internal global i1 false @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 = 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.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 @str.126 = private unnamed_addr constant [37 x i8] c"result = concat(result, substr(fmt, \00", align 1

View File

@@ -1,6 +1,6 @@
@g_should_call = internal global i1 false @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 = 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.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 @str.126 = private unnamed_addr constant [37 x i8] c"result = concat(result, substr(fmt, \00", align 1

View File

@@ -1,6 +1,6 @@
@g_should_call = internal global i1 false @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 = 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.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 @str.126 = private unnamed_addr constant [37 x i8] c"result = concat(result, substr(fmt, \00", align 1

View File

@@ -1,6 +1,6 @@
@g_should_call = internal global i1 false @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 = 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.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 @str.126 = private unnamed_addr constant [37 x i8] c"result = concat(result, substr(fmt, \00", align 1

View File

@@ -1,6 +1,6 @@
@g_should_call = internal global i1 false @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 = 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.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 @str.126 = private unnamed_addr constant [37 x i8] c"result = concat(result, substr(fmt, \00", align 1

View File

@@ -1,6 +1,6 @@
@g_should_call = internal global i1 false @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 = 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.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 @str.126 = private unnamed_addr constant [37 x i8] c"result = concat(result, substr(fmt, \00", align 1

View File

@@ -1,6 +1,6 @@
@g_should_call = internal global i1 false @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 = 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.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 @str.126 = private unnamed_addr constant [37 x i8] c"result = concat(result, substr(fmt, \00", align 1

View File

@@ -1,6 +1,6 @@
@g_should_call = internal global i1 false @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 = 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.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 @str.126 = private unnamed_addr constant [37 x i8] c"result = concat(result, substr(fmt, \00", align 1

View File

@@ -1,6 +1,6 @@
@g_should_call = internal global i1 false @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 = 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.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 @str.126 = private unnamed_addr constant [37 x i8] c"result = concat(result, substr(fmt, \00", align 1

View File

@@ -1,6 +1,6 @@
@g_held_view = internal global ptr null @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 = 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 @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 @jni.parent.path = private unnamed_addr constant [21 x i8] c"android/app/Activity\00", align 1

View File

@@ -962,6 +962,8 @@ pub const LLVMEmitter = struct {
c.LLVMSetInitializer(llvm_global, c.LLVMConstNull(llvm_ty)); 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 {}; self.global_map.put(@intCast(i), llvm_global) catch {};
} }
} }

View File

@@ -1587,6 +1587,8 @@ pub const Lowering = struct {
pub const fnPtrTypeWantsCtx = lower_decl.fnPtrTypeWantsCtx; pub const fnPtrTypeWantsCtx = lower_decl.fnPtrTypeWantsCtx;
pub const scanDecls = lower_decl.scanDecls; pub const scanDecls = lower_decl.scanDecls;
pub const registerTypedModuleConst = lower_decl.registerTypedModuleConst; 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 typedConstInitFits = lower_decl.typedConstInitFits;
pub const constExprInitFits = lower_decl.constExprInitFits; pub const constExprInitFits = lower_decl.constExprInitFits;
pub const registerTopLevelGlobal = lower_decl.registerTopLevelGlobal; pub const registerTopLevelGlobal = lower_decl.registerTopLevelGlobal;

View File

@@ -50,7 +50,12 @@ pub fn constArrayLiteral(self: *Lowering, elements: []const *const Node, array_t
/// expression is not constant-foldable here. /// expression is not constant-foldable here.
pub fn constExprValue(self: *Lowering, expr: *const Node, expected_ty: TypeId) ?inst_mod.ConstantValue { pub fn constExprValue(self: *Lowering, expr: *const Node, expected_ty: TypeId) ?inst_mod.ConstantValue {
return switch (expr.data) { 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 }, .bool_literal => |bl| .{ .boolean = bl.value },
// A float into an INTEGER destination follows the implicit // A float into an INTEGER destination follows the implicit
// narrowing rule: an integral float folds to its int, a // 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, .null_literal => .null_val,
.unary_op => |uo| switch (uo.op) { .unary_op => |uo| switch (uo.op) {
.negate => switch (uo.operand.data) { .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 }, .float_literal => |fl| .{ .float = -fl.value },
else => null, else => null,
}, },

View File

@@ -778,7 +778,10 @@ pub fn scanDecls(self: *Lowering, decls: []const *const Node) void {
self.setCurrentSourceFile(decl.source_file); self.setCurrentSourceFile(decl.source_file);
switch (decl.data) { switch (decl.data) {
.var_decl => self.registerTopLevelGlobal(&decl.data.var_decl), .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 => {}, else => {},
} }
} }
@@ -924,6 +927,95 @@ pub fn constExprInitFits(self: *Lowering, init_ty: TypeId, dst_ty: TypeId) bool
return init_ty == dst_ty; 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 = ---;`). /// Register a top-level mutable global (e.g., `context : Context = ---;`).
/// Run AFTER `resolveForwardIdentifierAliases` so a forward identifier alias /// Run AFTER `resolveForwardIdentifierAliases` so a forward identifier alias
/// in the type annotation (`A :: B; B :: s32; g : A = 7;`) resolves to its /// in the type annotation (`A :: B; B :: s32; g : A = 7;`) resolves to its