feat: lifetime elision, tooling CI, registry, and LSP locals

Ship the QUALITY_PLAN stretch from ownership through ecosystem: C.1
lifetime elision (bootstrap + selfhost), bux fmt/test/doc CI hooks,
stdlib goldens, package registry (bux search/add), and LSP 0.4
position-sensitive locals with inferred let types. Full-tree format
pass plus Map/Set remove double-free fix.
This commit is contained in:
2026-07-19 16:35:08 +03:00
parent 3eb1ad3a82
commit 53b43b0f79
130 changed files with 20494 additions and 16738 deletions
+4 -4
View File
@@ -10,20 +10,20 @@ enum Result {
func Main() -> int {
let r1: Result = Result { tag: Result_Ok };
r1.data.Ok_0 = 42;
let r2: Result = Result { tag: Result_Err };
r2.data.Err_0 = "error message";
if r1.tag == Result_Ok {
PrintLine("r1 is Ok:");
PrintInt(r1.data.Ok_0);
PrintLine("");
}
if r2.tag == Result_Err {
PrintLine("r2 is Err:");
PrintLine(r2.data.Err_0);
}
return 0;
}
+2 -2
View File
@@ -1,8 +1,8 @@
// borrow.bux — Test explicit borrow expressions
struct Point {
x: int;
y: int;
x: int;
y: int;
}
// NOT @[Checked] — borrow keyword available everywhere
+2 -2
View File
@@ -23,12 +23,12 @@ func ColorName(c: Color) -> String {
func Main() -> int {
let myColor: Color = Color::Green;
PrintLine("My color is:");
PrintLine(ColorName(myColor));
PrintLine("Color value:");
PrintInt(myColor as int);
PrintLine("");
return 0;
}
+1 -1
View File
@@ -27,4 +27,4 @@ func Main() -> int {
PrintLine("");
return 0;
}
}
+2 -2
View File
@@ -11,13 +11,13 @@ func Factorial(n: int) -> int {
func Main() -> int {
PrintLine("Factorials:");
var i: int = 1;
while i <= 10 {
let fact: int = Factorial(i);
PrintLine(Fmt_Fmt2("{0}! = {1}", String_FromInt(i), String_FromInt(fact)));
i = i + 1;
}
return 0;
}
+2 -2
View File
@@ -11,13 +11,13 @@ func Fibonacci(n: int) -> int {
func Main() -> int {
PrintLine("Fibonacci sequence:");
var i: int = 0;
while i < 10 {
let fib: int = Fibonacci(i);
PrintLine(Fmt_Fmt1("{0}", String_FromInt(fib)));
i = i + 1;
}
return 0;
}
+4 -4
View File
@@ -13,14 +13,14 @@ func Main() -> int {
// Inferred: T = int
let m1: int = Max(10, 20);
let m2: int = Max(5, 3);
PrintLine("Max(10, 20) = ");
PrintInt(m1);
PrintLine("");
PrintLine("Max(5, 3) = ");
PrintInt(m2);
PrintLine("");
return 0;
}
}
+1 -1
View File
@@ -20,4 +20,4 @@ func Main() -> int {
PrintInt(p.GetFirst());
PrintLine("");
return 0;
}
}
+3 -3
View File
@@ -13,14 +13,14 @@ func Max<T>(a: T, b: T) -> T {
func Main() -> int {
let m1: int = Max<int>(10, 20);
let m2: int = Max<int>(5, 3);
PrintLine("Max(10, 20) = ");
PrintInt(m1);
PrintLine("");
PrintLine("Max(5, 3) = ");
PrintInt(m2);
PrintLine("");
return 0;
}
+4 -4
View File
@@ -31,21 +31,21 @@ func Main() -> int {
PrintLine("Box value:");
PrintInt(b.Get());
PrintLine("");
b.Set(100);
PrintLine("Box after Set(100):");
PrintInt(b.Get());
PrintLine("");
let p: Pair<int, String> = Pair<int, String> { first: 10, second: "hello" };
PrintLine("Pair first:");
PrintInt(p.GetFirst());
PrintLine("");
let bp: *Box<int> = &b;
PrintLine("Box via pointer:");
PrintInt(bp.Get());
PrintLine("");
return 0;
}
+5 -5
View File
@@ -5,20 +5,20 @@ import Std::Fmt::{Fmt_Fmt1, Fmt_FmtInt};
func Main() -> int {
PrintLine("=== Json Demo ===");
let s: String = "{\"name\":\"Bux\",\"count\":42,\"items\":[\"a\",\"b\",\"c\"]}";
let j: JsonValue = Json_Parse(s);
PrintLine("Parsed and stringified:");
PrintLine(Json_Stringify(j));
PrintLine("\nAccess fields:");
PrintLine(Fmt_Fmt1("name = {0}", Json_AsString(Json_ObjectGet(j, "name"))));
PrintLine(Fmt_FmtInt("count = {0}", Json_AsNumber(Json_ObjectGet(j, "count")) as int64));
let items: JsonValue = Json_ObjectGet(j, "items");
PrintLine(Fmt_Fmt1("items[0] = {0}", Json_AsString(Json_ArrayGet(items, 0))));
PrintLine(Fmt_Fmt1("items[1] = {0}", Json_AsString(Json_ArrayGet(items, 1))));
PrintLine("\nBuild JSON programmatically:");
var obj: JsonValue = Json_Object();
Json_ObjectSet(&obj, "lang", Json_String("Bux"));
@@ -28,6 +28,6 @@ func Main() -> int {
Json_ArrayPush(&arr, Json_String("safe"));
Json_ObjectSet(&obj, "tags", arr);
PrintLine(Json_Stringify(obj));
return 0;
}
+7 -7
View File
@@ -29,30 +29,30 @@ func Jwt_Create(payload: JsonValue, secret: String) -> String {
let header: JsonValue = Json_Object();
Json_ObjectSet(&header, "alg", Json_String("HS256"));
Json_ObjectSet(&header, "typ", Json_String("JWT"));
let headerB64: String = Base64UrlEncode(Json_Stringify(header));
let payloadB64: String = Base64UrlEncode(Json_Stringify(payload));
let signingInput: String = String_Concat(headerB64, ".");
signingInput = String_Concat(signingInput, payloadB64);
let sigRaw: String = Crypto_HmacSha256Raw(secret, signingInput);
let sigB64: String = Base64UrlEncodeSig(sigRaw);
return String_Concat(String_Concat(signingInput, "."), sigB64);
}
func Main() -> int {
PrintLine("=== JWT Demo ===");
let payload: JsonValue = Json_Object();
Json_ObjectSet(&payload, "sub", Json_String("user123"));
Json_ObjectSet(&payload, "name", Json_String("Bux Developer"));
Json_ObjectSet(&payload, "admin", Json_Bool(true));
let token: String = Jwt_Create(payload, "my-secret-key");
PrintLine("Token:");
PrintLine(token);
return 0;
}
+51
View File
@@ -0,0 +1,51 @@
// lifetime_elision.bux — C.1: elided lifetimes for common &[Checked] APIs
// No 'a annotations needed when there is a single input reference.
import Std::Io::{PrintLine, PrintInt};
import Std::Test::{Test_AssertEqInt, Test_Pass};
// Elided: param and return share one lifetime automatically
@[Checked]
func Identity(p: &int) -> &int {
return p;
}
// Explicit lifetime for documentation / multi-ref (same lifetime both sides)
@[Checked]
func IdentityNamed<'a>(p: &'a int) -> &'a int {
return p;
}
// Via intermediate let binding — lifetime is propagated
@[Checked]
func ViaLet(p: &int) -> &int {
let r: &int = p;
return r;
}
// self-style first param: elision prefers the first input for the return
@[Checked]
func FirstOf(self: &int, _other: int) -> &int {
return self;
}
@[Checked]
func Main() -> int {
var x: int = 10;
var y: int = 20;
let a: &int = Identity(&x);
Test_AssertEqInt(*a, 10);
let b: &int = IdentityNamed(&y);
Test_AssertEqInt(*b, 20);
let c: &int = ViaLet(&x);
Test_AssertEqInt(*c, 10);
let d: &int = FirstOf(&y, 0);
Test_AssertEqInt(*d, 20);
Test_Pass("lifetime_elision");
PrintLine("lifetime_elision: ok");
return 0;
}
+7 -7
View File
@@ -5,26 +5,26 @@ import Std::Map::{Map, Map_New, Map_Set, Map_Get, Map_Has, Map_Free};
func Main() -> int {
PrintLine("=== Map<int, String> ===");
let m: Map<int, String> = Map_New<int, String>(16);
Map_Set<int, String>(&m, 1, "one");
Map_Set<int, String>(&m, 2, "two");
Map_Set<int, String>(&m, 3, "three");
PrintLine("Get 1:");
PrintLine(Map_Get<int, String>(&m, 1));
PrintLine("Get 2:");
PrintLine(Map_Get<int, String>(&m, 2));
if Map_Has<int, String>(&m, 1) {
PrintLine("Has 1: yes");
}
// Test update
Map_Set<int, String>(&m, 2, "updated");
PrintLine("Updated 2:");
PrintLine(Map_Get<int, String>(&m, 2));
Map_Free<int, String>(&m);
return 0;
}
}
+3 -3
View File
@@ -11,7 +11,7 @@ extend Rectangle {
func Area(self: Rectangle) -> int {
return self.width * self.height;
}
func Perimeter(self: Rectangle) -> int {
return 2 * (self.width + self.height);
}
@@ -19,7 +19,7 @@ extend Rectangle {
func Main() -> int {
let rect: Rectangle = Rectangle { width: 10, height: 5 };
PrintLine("Rectangle:");
PrintLine("Width = ");
PrintInt(rect.width);
@@ -33,6 +33,6 @@ func Main() -> int {
PrintLine("Perimeter = ");
PrintInt(rect.Perimeter());
PrintLine("");
return 0;
}
+3 -3
View File
@@ -9,16 +9,16 @@ func Main() -> int {
PrintLine(Fmt_Fmt1("Current directory: {0}", Os_GetCwd()));
PrintLine(Fmt_FmtInt("Command-line args: {0}", Os_ArgsCount() as int64));
PrintLine(Fmt_Fmt1("HOME env: {0}", Os_GetEnv("HOME")));
PrintLine("\n=== Time Demo ===");
let start: int64 = Time_NowMs();
PrintLine(Fmt_FmtInt("Start: {0} ms", start));
PrintLine("Sleeping 150ms...");
Time_SleepMs(150);
let end: int64 = Time_NowMs();
PrintLine(Fmt_FmtInt("End: {0} ms", end));
PrintLine(Fmt_FmtInt("Elapsed: {0} ms", end - start));
return 0;
}
+4 -4
View File
@@ -23,17 +23,17 @@ func UncheckedSwap(a: *int, b: *int) {
func Main() -> int {
var x: int = 10;
// &mut allows mutation
ScaleInPlace(&x, 3);
PrintInt(x); // 30
PrintLine("");
// & allows reading
let y: int = GetValue(&x);
PrintInt(y); // 30
PrintLine("");
// Unchecked: raw pointers work like C
var a: int = 5;
var b: int = 7;
@@ -42,6 +42,6 @@ func Main() -> int {
PrintLine("");
PrintInt(b); // 5
PrintLine("");
return 0;
}
+3 -3
View File
@@ -5,12 +5,12 @@ import Std::Fmt::{Fmt_Fmt1, Fmt_FmtInt};
func Main() -> int {
PrintLine("Process demo:");
let output: String = Process_Output("echo Hello from subprocess");
PrintLine(Fmt_Fmt1("Captured: {0}", output));
let rc: int = Process_Run("true");
PrintLine(Fmt_FmtInt("Exit code: {0}", rc));
return 0;
}
+6 -6
View File
@@ -82,14 +82,14 @@ func SafeDivide(a: int, b: int) -> Option {
func Main() -> int {
PrintLine("Result demo:");
let r1: Result = Divide(10, 2);
if Result_IsOk(r1) {
PrintLine("10 / 2 = ");
PrintInt(Result_Unwrap(r1));
PrintLine("");
}
let r2: Result = Divide(10, 0);
if Result_IsErr(r2) {
PrintLine("10 / 0 failed");
@@ -97,20 +97,20 @@ func Main() -> int {
PrintLine("unwrap_or = ");
PrintInt(Result_UnwrapOr(r2, -1));
PrintLine("");
PrintLine("Option demo:");
let o1: Option = SafeDivide(20, 4);
if Option_IsSome(o1) {
PrintLine("20 / 4 = ");
PrintInt(Option_UnwrapOr(o1, 0));
PrintLine("");
}
let o2: Option = SafeDivide(20, 0);
PrintLine("20 / 0 fallback = ");
PrintInt(Option_UnwrapOr(o2, -1));
PrintLine("");
return 0;
}
+7 -7
View File
@@ -5,30 +5,30 @@ import Std::String::{String_Len, String_Eq, String_Concat};
func Main() -> int {
let hello: String = "Hello";
let world: String = "World";
PrintLine("String operations:");
// Length
PrintLine("Length of 'Hello':");
PrintInt(String_Len(hello));
PrintLine("");
// Concatenation
let greeting: String = String_Concat(hello, ", ");
let greeting2: String = String_Concat(greeting, world);
let full: String = String_Concat(greeting2, "!");
PrintLine("Concatenated:");
PrintLine(full);
// Equality
if String_Eq(hello, "Hello") {
PrintLine("'Hello' equals 'Hello'");
}
if !String_Eq(hello, world) {
PrintLine("'Hello' does not equal 'World'");
}
return 0;
}
+2 -2
View File
@@ -65,10 +65,10 @@ func Main() -> int {
StringBuilder_Append(&sb, "World");
StringBuilder_Append(&sb, "! #");
StringBuilder_AppendInt(&sb, 42);
Print("StringBuilder: ");
PrintLine(StringBuilder_Build(&sb));
StringBuilder_Free(&sb);
return 0;
}
}
+2 -2
View File
@@ -16,7 +16,7 @@ func Main() -> int {
let p1: Point = Point { x: 10, y: 20 };
let p2: Point = Point { x: 5, y: 15 };
let sum: Point = AddPoints(p1, p2);
PrintLine("Point sum:");
PrintLine("x = ");
PrintInt(sum.x);
@@ -24,6 +24,6 @@ func Main() -> int {
PrintLine("y = ");
PrintInt(sum.y);
PrintLine("");
return 0;
}
+3 -3
View File
@@ -39,7 +39,7 @@ func ComputeWithError() -> Result {
func Main() -> int {
PrintLine("Try operator demo:");
let r1: Result = Compute();
if r1.tag == Result_Ok {
PrintLine("Compute() = ");
@@ -48,11 +48,11 @@ func Main() -> int {
} else {
PrintLine("Compute() failed");
}
let r2: Result = ComputeWithError();
if r2.tag == Result_Err {
PrintLine("ComputeWithError() failed as expected");
}
return 0;
}