Releases: vixlang/Vix-lang
v0.4.3
Full Changelog: v0.4.2...v0.4.3
Vix Language v0.4.3 Release Notes
Release Date: June 19, 2026
Overview
Vix 0.4.3 focuses on fixing struct-related code generation bugs, improving array indexing with struct elements, and enhancing semantic analysis accuracy.
Bug Fixes
For-Range Loop
- Fixed for-range direction bug:
for (i in 1..n)now uses half-open ascending range semantics (<comparison) instead of bidirectional logic, simplifying behavior and fixing edge cases with empty ranges (e.g.,1..0correctly executes zero iterations)
Array Indexing with Struct Elements
- Struct element type hints:
computeIndexPtrandvisitIndexAssignnow checkpointerElementHintsbefore falling back togetPointerElementTypeSafely, fixing type resolution when indexing arrays of structs - Pointer-to-struct indexing:
visitIndexnow correctly propagates struct type hints through PHI nodes when indexing pointer-to-struct arrays, usingstorageElemTypefor null values and GEP operations
Struct Push Operations
- Struct push codegen: Array
push()with struct values now heap-allocates the struct and stores a pointer with proper type hints, instead of attempting inline struct storage which caused LLVM type mismatches
Function Argument Passing
- Struct-to-ptr argument conversion: Struct values are now automatically converted to pointers when passed to
ptr-typed function parameters, with properpointerElementHintstracking
Array Length Inference
- Extended array length inference:
inferArrayLengthFromArgumentnow handles pointer arguments, global variables, member access expressions, and index expressions for.lenresolution
Semantic Analysis
- Struct literal variable tracking:
is_variable_used_in_nodenow correctly detects variable usage inside struct literals (e.g.,State{tape: tape, ptr: 0}) - Struct literal unused variable check:
check_unused_variables_with_usagenow traverses struct literal fields to avoid false "unused variable" warnings
New Regression Tests
- test404.vix: Validates for-range edge cases — empty range
1..0, single-iteration1..1, and normal range1..2 - test405.vix: Tests struct member array indexing, mutation via pointer methods, and struct field state tracking
Build System
- Moved
examples/Coreutils/echo.vixtoexamples/coreutils/echo.vix(lowercase directory)
Known Issues
- Some ownership tests correctly fail (expected behavior for error detection)
- Some import tests fail due to missing module files (not compiler bugs)
v0.4.2
Full Changelog: v0.4.1...v0.4.2
Vix Language v0.4.2 Release Notes
Release Date: June 18, 2026
Overview
Vix 0.4.2 introduces the LLVM backend for vixc0 (the self-hosted compiler), along with several compiler improvements and bug fixes.
New Features
LLVM Backend for vixc0
- LLVM C API Integration: vixc0 now uses the LLVM C API for code generation instead of the QBE backend
- helper.c Wrapper: A C helper file (
vixc0/helper.c) wraps LLVM C API functions that require array parameters, enabling vixc to call them - Variable Tracking: Added global variable tracking system for LLVM IR generation, allowing proper alloca/store/load operations
Compiler Improvements
- Void Extern Functions: The parser now supports extern "C" functions without return types (void functions)
- Array to Ptr Conversion: Type checking now allows passing arrays to
ptrparameters with implicit decay -lLinker Flag: Added support for-l <lib>flag to specify additional libraries to linkglobalKeyword Fix: Theglobalkeyword can now be used as an identifier in extern declarations
vixc0 Enhancements
- File Input: vixc0 can now read and compile
.vixfiles directly (e.g.,./vixc0 test.vix) - Improved Argument Parsing: Better handling of command-line arguments with
.vixfile detection
Bug Fixes
Parser Fixes
- Fixed parsing of void extern functions that caused syntax errors
- Fixed
globalkeyword not returning any token in the lexer
Type System Fixes
- Fixed type checking to allow array-to-ptr implicit conversion in function arguments
- Fixed return value handling in LLVM backend (proper load before return)
Code Generation Fixes
- Fixed LLVM function type creation to use proper parameter arrays
- Fixed alloca results not being tracked for subsequent store/load operations
- Fixed LLVM API function names for LLVM 22 compatibility (
LLVMBuildLoad2,LLVMBuildGEP2,LLVMBuildCall2)
Build System
- Updated build.sh: Now compiles
helper.cand links with LLVM libraries - LLVM Linking: Uses
-l LLVM-22to link against LLVM 22
Testing
All .vix files in the following directories have been tested:
examples/: 50+ example files compile successfullytests/regression/: 170+ regression tests pass (some expected failures for ownership/error tests)std/: All standard library modules compile successfully
Known Issues
- Some ownership tests correctly fail (expected behavior for error detection)
- Some import tests fail due to missing module files (not compiler bugs)
- stdin input mode still reads from hardcoded test file (existing issue)
Contributors
- Daweidie
v0.4.1
Full Changelog: v0.4.0...v0.4.1
Vix 0.4.1 Release Notes
Overview
Vix 0.4.1 standardizes the generic syntax by removing the <> angle bracket syntax and keeping only the :[T] bracket syntax for all generic constructs. This change resolves syntax conflicts between generic types and comparison operators, providing a cleaner and unambiguous grammar.
Breaking Changes
Removed <> Generic Syntax
The <> angle bracket syntax for generics has been completely removed. All generic constructs now use :[T] bracket syntax exclusively.
Before (removed):
// Type definitions
type Result<T, E> = Ok(T) | Err(E)
struct Box<T> { value: T }
// Function definitions
fn id<T>(x: T): T { return x }
fn add<T>(a: T, b: T): T { return a + b }
// Impl blocks
impl Box<T> {
fn new(value: T): Box<T> { return Box:[T]{ value: value } }
}
// Function calls
let x = id<i32>(42)
let y = add<i32>(4, 6)
// Struct literals
let b = Box<i32>{ value: 10 }
// Type references
let arr: Box<i32> = b
After (required):
// Type definitions
type Result:[T, E] = Ok(T) | Err(E)
struct Box:[T] { value: T }
// Function definitions
fn id:[T](x: T): T { return x }
fn add:[T](a: T, b: T): T { return a + b }
// Impl blocks
impl Box:[T] {
fn new(value: T): Box:[T] { return Box:[T]{ value: value } }
}
// Function calls
let x = id:[i32](42)
let y = add:[i32](4, 6)
// Struct literals
let b = Box:[i32]{ value: 10 }
// Type references
let arr: Box:[i32] = b
Migration Guide
To migrate existing code:
- Replace all
TypeName<T>withTypeName:[T] - Replace all
fn name<T>withfn name:[T] - Replace all
impl Name<T>withimpl Name:[T] - Update type references from
Name<T>toName:[T] - Ensure nested generics like
Box<Box<i32>>becomeBox:[Box:[i32]]
What Changed
- Parser: Removed 16 grammar rules for
<>angle bracket syntax - Examples: Updated 5 example files to use
:[T]syntax - Standard Library: Updated 4 std files to use
:[T]syntax - Tests: Updated 37 regression test files and test_types.py to use
:[T]syntax - Documentation: Updated release notes
Compatibility
- The bootstrap compiler (
vixc0/) already uses:[T]syntax - All existing code using
<>syntax must be updated to compile - The
:[T]syntax is now the only supported generic syntax
Why This Change?
- Eliminates Ambiguity: The
<>syntax conflicted with comparison operators (<,>,<=,>=), making parsing ambiguous in some contexts - Consistency: All generic constructs now use the same syntax pattern
- Simpler Grammar: Reduces parser complexity and shift/reduce conflicts
- Array Distinction: Clearly distinguishes between array types
[T]and generic typesName:[T]
Known Issues
- None reported for this change
Contributors
- Daweidie
v0.4.0-dev
Full Changelog: v0.4.0...v0.4.0-dev
Vix 0.4.0-dev Release Notes
Overview
Vix 0.4.0-dev removes the legacy [] bracket generic syntax and standardizes on <> angle bracket syntax for all generic constructs. This is a breaking change that simplifies the language grammar and improves consistency.
Breaking Changes
Removed [] Generic Syntax
The :[T] bracket syntax for generics has been completely removed. All generic constructs now use <> angle brackets exclusively.
Before (removed):
// Type definitions
type Result:[T, E] = Ok(T) | Err(E)
struct Box:[T] { value: T }
// Function definitions
fn id:[T](x: T): T { return x }
fn add:[T](a: T, b: T): T { return a + b }
// Function calls
let x = id:[i32](42)
let y = add:[i32](4, 6)
// Struct literals
let b = Box:[i32]{ value: 10 }
// Type references
let arr: Box:[i32] = b
After (required):
// Type definitions
type Result<T, E> = Ok(T) | Err(E)
struct Box<T> { value: T }
// Function definitions
fn id<T>(x: T): T { return x }
fn add<T>(a: T, b: T): T { return a + b }
// Function calls
let x = id<i32>(42)
let y = add<i32>(4, 6)
// Struct literals
let b = Box<i32>{ value: 10 }
// Type references
let arr: Box<i32> = b
Migration Guide
To migrate existing code:
- Replace all
:[with<and corresponding]with> - Update type references from
TypeName[T]toTypeName<T> - Ensure nested generics like
Box<Box:[i32]]becomeBox<Box<i32>>
What Changed
- Parser: Removed 16 grammar rules for
:[T]bracket syntax - Examples: Updated 5 example files to use
<>syntax - Tests: Updated 32 regression test files to use
<>syntax - Documentation: Updated release notes and compiler documentation
Compatibility
- The standard library (
std/) already uses<>syntax - The bootstrap compiler (
vixc0/) already uses<>syntax - All existing code using
:[T]syntax must be updated to compile
Known Issues
- None reported for this change
Contributors
- Daweidie
v0.4.0
Full Changelog: v0.3.3...v0.4.0
v0.3.3-dev
Full Changelog: v0.3.0...v0.3.3-dev
Vix Compiler v0.3.3-dev Release Notes
Release Date: June 13, 2026
Overview
Vix v0.3.3-dev is a development release focused on syntax modernization, ADT bug fixes, boolean type support, and compiler correctness fixes. Key changes include replacing the ref keyword with & for safe references, adding proper true/false boolean literals, fixing custom ADT constructors and match expressions, and expanding the vixc0 bootstrap compiler.
What's New
Syntax Change: ref replaced by &
The ref keyword has been replaced by the & symbol for safe references. This applies to both type annotations and expressions:
- Type position:
ref i32is now&i32 - Expression position:
ref xis now&x - Mutable reference:
mut ref xis nowmut &x
Example:
fn add(a: &i32, b: &i32): i32 {
return @a + @b
}
fn main(): i32 {
let x = 7
let y = 8
print(add(&x, &y))
return 0
}
Proper Boolean Type
true and false are now proper boolean literals with type bool, instead of being aliases for 1 and 0 as i32:
truehas typebool(previouslyi32)falsehas typebool(previouslyi32)- Comparison operators (
==,!=,<,<=,>,>=) returnboolvalues - Boolean operators (
and,or,!) work withbooltype
Custom ADT Constructor Fixes
Fixed several bugs with custom Algebraic Data Type (ADT) constructors:
- Payload type resolution: ADT constructors with payloads (e.g.,
Int(i32)) now correctly resolve the payload type from the type definition, instead of using a fresh type variable. - Tag value consistency: Custom ADT constructors now use the constructor index as the tag value (consistent with the parser), instead of a hash of the constructor name.
- Match with custom ADTs: Match expressions with custom ADT constructor patterns (both simple identifiers like
Redand payload patterns likeInt(v)) now correctly compare tag values. - Function-local ADTs: ADT definitions inside functions now generate correct tag values, matching the behavior of top-level ADT definitions.
- No-payload constructors: Simple enum constructors without payloads (e.g.,
Red,Green,Blue) now create proper tagged structs instead of returning raw integer values.
vixc0 Bootstrap Compiler
The vixc0 bootstrap compiler has been expanded with:
- Multi-token lexer support for
&,true,false, escape sequences - Expression parser with operator precedence (arithmetic, comparison, logical)
letstatements,printstatements, assignment statements- QBE IR codegen for expressions and basic statements
Bug Fixes
Ownership Checker
- Copy Classification Fixes:
stringandstructvalues are no longer incorrectly treated as Copy by the Owner pass.- Assigning a
stringnow moves ownership instead of silently allowing reuse of the source variable. - Assigning a
structthat contains non-Copy data now also moves ownership as expected.
- Assigning a
- Removed Copy Naming Hack: Ownership no longer treats identifiers starting with an uppercase letter as implicitly Copy.
- This closes a hole where move checks could be bypassed by variable naming alone.
- By-Value Call Semantics: Function calls now distinguish between by-value and
&arguments.- Non-
¶meters consume non-Copy arguments. ¶meters are checked as borrows instead of generic reads.
- Non-
- Persistent Borrow Tracking: Borrows stored in variables now remain active across statements until the borrow variable leaves scope or is reassigned.
- This prevents mutating a value while an outstanding borrow to it still exists.
- Improved Borrow Source Propagation: Ownership now preserves borrow provenance through more expression forms.
- Member access and indexing now retain the underlying borrowed base.
- Borrow provenance is also propagated through simple expression and call-return paths needed for dangling-reference detection.
- Indirect Dangling Reference Detection: Returning a local reference through an intermediate function call is now rejected.
Example now correctly rejected:
fn take(xs: [i32]): i32 {
return xs[0]
}
fn main(): i32 {
let xs = [1, 2, 3]
print(take(xs))
print(xs[0])
return 0
}
Diagnostic:
error [SemanticError]: use of moved value 'xs'
Borrow stored across statements is now also rejected:
fn main(): i32 {
let mut x = 1
let r = mut &x
x = 2
print(@r)
return 0
}
Diagnostic:
error [SemanticError]: cannot assign to 'x' while it is borrowed
Lexer & String Processing
- Octal Escape Sequences: Added support for octal escape sequences (e.g.,
\033) in string literals. This enables proper handling of ANSI escape codes for terminal control.- Example:
printf("\033[2J\033[H")now correctly outputs screen clearing sequences - Previously,
\033was incorrectly parsed as\0followed by literal characters
- Example:
Type Checker
- Void Function Returns: Fixed type checking for void functions that don't have explicit return statements
- Functions declared with
voidreturn type no longer require explicitreturnstatements - Improved type inference for function bodies
- Functions declared with
Code Changes
Modified Files
src/parser/lexer.l: Removedrefkeyword token (replaced by&symbol)src/parser/parser.y: RemovedREF_KWgrammar rules, unified reference syntax underAMPERSANDsrc/Ownership/Ownership.cpp: Corrected move/copy classification, call-site ownership handling, persistent borrow tracking, and dangling-reference propagationsrc/Typeck/Typeck.cpp: Improved void function type checkingsrc/compiler/Stmts.cpp: Minor statement handling improvementssrc/compiler/Structs.cpp: Struct processing enhancementsexamples/*.vix: Updated all examples fromrefto&syntaxtests/test_ownership.py: Updated test source strings for&syntaxtests/test_types.py: Updated test source strings for&syntaxtests/feat.py: Updated test source strings for&syntaxtests/regression/ownership_return_via_call.vix: Updated to&syntaxtests/regression/ownership_persistent_borrow.vix: Updated to&syntax
New Files
src/ed.vix: Text editor implementation in Vix languagesrc/test_cursor2.vix: Test program for cursor movement functionalitytests/regression/ownership_string_move.vix: Regression fixture for string move errorstests/regression/ownership_struct_move.vix: Regression fixture for struct move errorstests/regression/ownership_call_move.vix: Regression fixture for by-value call move semanticstests/regression/ownership_persistent_borrow.vix: Regression fixture for borrow-across-statement assignment rejectiontests/regression/ownership_return_via_call.vix: Regression fixture for indirect dangling-reference rejection
Technical Details
Octal Escape Sequence Support
The lexer now properly handles octal escape sequences in the format \NNN where N is an octal digit (0-7):
printf("\033[2J\033[H")
printf("\033[10;5H") // Move to row 10, column 5
printf("\033[31m") // Set red text color
Arrow Key Handling
The editor now processes ANSI arrow key sequences:
- Up Arrow:
\033[A - Down Arrow:
\033[B - Right Arrow:
\033[C - Left Arrow:
\033[D
Ownership Validation
Ownership-focused validation in this release covered:
- Use-after-move for arrays, strings, and structs.
- By-value function call move semantics.
- Shared and mutable borrow conflict checks.
- Borrow persistence across statements when a reference is stored in a variable.
- Indirect dangling local reference detection through function returns.
Targeted validation performed:
- Rebuilt
vixcsuccessfully with the updatedsrc/Ownership/Ownership.cpp. - Ran
venv/bin/pytest tests/test_ownership.pysuccessfully. - Verified dedicated regression fixtures fail with the expected ownership diagnostics.
Installation
From Source
git clone https://github.com/vixlang/Vix-lang.git
cd Vix-lang
mkdir build && cd build
cmake ..
make
sudo make installUsing Pre-built Binaries
Download the appropriate binary for your platform from the releases page.
Known Issues
- Some warnings are generated during compilation of example files (unused variables)
- The Owner system still does not implement full non-lexical lifetimes, control-flow-sensitive move joins, or field-level partial move analysis
Upgrading
This release introduces a syntax change: the ref keyword is replaced by & for safe references. All code using ref must be updated:
ref T(type) →&Tref x(expression) →&xmut ref x→mut &x
This is also intended to be source-compatible for valid programs (with the syntax update), but some code that previously compiled due to ownership-checker gaps will now be rejected.
In particular, v0.3.1 now diagnoses:
- Reuse of moved
stringandstructvalues. - Reuse of non-Copy values after passing them to by-value function parameters.
- Mutation while a borrow stored in a variable is still live.
- Returning references to locals through simple intermediate call paths.
Contributors
- Daweidie
Feedback
Please report any issues or feature requests on our GitHub Issues page.
For more information about the Vix programming language, visit vixlang.github.io.
v0.3.3
Full Changelog: v0.3.0...v0.3.3
Vix Compiler v0.3.3 Release Notes
Release Date: June 13, 2026
Overview
Vix v0.3.3 focuses on match expression enhancements, making match more powerful and ergonomic. Key improvements include using match as an expression, supporting member access as scrutinee, and adding multi-pattern arms with |.
What's New
Match Expression Enhancements
Match as Expression
match can now be used as an expression that returns a value:
let result = match tag {
"int" -> 1
"bool" -> 2
_ -> 0
}
This enables more concise code when assigning values based on pattern matching.
Member Access as Scrutinee
Match expressions now support member access expressions as the scrutinee:
match expr.tag {
"int" -> "integer"
"string" -> "text"
_ -> "other"
}
Previously, only simple identifiers and literals were supported as the scrutinee.
Multi-Pattern Arms
Match expressions now support multiple patterns separated by | (pipe) for the same arm:
match tag {
"int" | "bool" | "string" -> "Literal"
"ident" -> "Identifier"
"binop" -> "BinaryExpression"
_ -> "Unknown"
}
This desugars to OR conditions: (tag == "int") or (tag == "bool") or (tag == "string").
Bug Fixes
Member Access Scrutinee
Fixed a bug where match with member access expressions (e.g., match expr.tag { ... }) would fail at runtime. The clone_match_scrutinee function now correctly handles AST_MEMBER_ACCESS nodes.
Code Changes
Modified Files
src/parser/parser.y: Added match expression, member access scrutinee, and multi-pattern arm supportinclude/ast.h: Addedis_multi_patternfield to assign node for multi-pattern match arms
Installation
From Source
git clone https://github.com/vixlang/Vix-lang.git
cd Vix-lang
mkdir build && cd build
cmake ..
make
sudo make installUsing Pre-built Binaries
Download the appropriate binary for your platform from the releases page.
Upgrading
This release is backward compatible. No code changes are required to upgrade from v0.3.2.
Contributors
- Vix Language Team
Feedback
Please report any issues or feature requests on our GitHub Issues page.
For more information about the Vix programming language, visit vixlang.github.io.
v0.3.0
Full Changelog: v0.2.10...v0.3.0
Vix Language v0.3.0 Release Notes
Release Date: 2026-06-07
New Features
Lightweight Owner system
Vix v0.3.0 introduces the first version of the lightweight Owner system: a compile-time ownership and borrow checker designed to provide most of Rust-style memory safety with a much simpler language model.
The goal of this release is practical safety without Rust-level complexity:
- Ownership transfer for non-Copy values.
- Exclusive mutable references.
- Shared immutable references.
- Use-after-move detection.
- Dangling local reference detection.
- Copy-type inference for small/simple values.
- Statement-scoped temporary borrows as a simplified “last use” model.
The Owner pass runs after type checking, using inferred AST type information from typecheck_program(...).
Files:
include/ownership.hsrc/Ownership/Ownership.cppsrc/main.cCMakeLists.txt
New reference syntax: ref and mut ref
References now use explicit keyword syntax instead of the old & spelling.
Immutable shared reference:
fn read(x: ref i32): i32
{
return @x
}
fn main(): i32
{
let value = 10
print(read(ref value))
return 0
}
Mutable exclusive reference:
fn inc(mut p: ref i32)
{
@p = @p + 1
}
fn main(): i32
{
let mut value = 10
inc(mut ref value)
print(value)
return 0
}
Rules:
ref valuecreates an immutable shared borrow.mut ref valuecreates a mutable exclusive borrow.- A value may have many immutable borrows in the same statement.
- A mutable borrow cannot overlap another mutable or immutable borrow in the same statement.
- Temporary borrows are released at the end of the statement.
The parser still maps references internally to the existing pointer AST representation, so existing code generation can continue to reuse pointer lowering.
Files:
src/parser/lexer.lsrc/parser/parser.ysrc/Ownership/Ownership.cpp
Move checking for non-Copy values
Non-Copy values are moved by ownership-transfer operations such as assignment into another variable.
Example rejected by the Owner checker:
fn main(): i32
{
let xs = [1, 2, 3]
let ys = xs
return xs[0]
}
Diagnostic:
error [SemanticError]: use of moved value 'xs'
Legal last-use move:
fn take(xs: [i32]): i32
{
return xs[0]
}
fn main(): i32
{
let xs = [1, 2, 3]
let ys = xs
return take(ys)
}
Copy type inference
The Owner system uses a heuristic Copy model instead of requiring explicit user annotations.
Currently treated as Copy:
- Integer types.
- Floating-point types.
- Boolean values.
- References/pointers.
- Function values.
- Strings as lightweight reference-like values.
- Struct values in the current lightweight model.
- Small fixed-size arrays when their element type is Copy.
- Uppercase enum-like constructors/constants.
Currently treated as non-Copy:
- Dynamic arrays.
- Generic application/container values by default.
This keeps common Vix code ergonomic while still catching important ownership errors around arrays, containers, references, and moves.
Dangling reference checks
The Owner checker rejects returning a reference to a local variable.
Example rejected:
fn bad(): ref i32
{
let local = 99
return ref local
}
Diagnostic:
error [SemanticError]: cannot return reference to local variable 'local'
Optional references
Optional references can be expressed with ?ref T.
fn maybe_ref(flag: i32, value: ref i32): ?ref i32
{
if (flag == 0)
{
return None
}
return Some(value)
}
This provides a simple way to model “maybe a reference” without explicit lifetime annotations.
Diagnostics
Ownership diagnostics now include file, line, and column
Example:
error [SemanticError]: use of moved value 'xs'
--> src/test.vix:15:11
|
14 | print(ys[0])
15 | return xs[0]
| ^
Fixes:
- Ownership errors now fall back to
current_input_filenamewhen AST nodes do not havesource_fileset. - Ownership errors now call
set_location_with_column(...)before reporting. - Parser-generated unary reference/deref nodes now preserve source locations through
create_unaryop_node_with_yyltype(...).
Files:
src/Ownership/Ownership.cppsrc/parser/parser.y
Examples and Tests
Updated examples for ref
The following examples were updated from old & reference syntax to ref:
examples/quicksort.vixexamples/swap.vixexamples/pointer.vixexamples/pointer2.vixexamples/nullptr.vixexamples/list.vix
Ownership test fixture
src/test.vix now acts as a negative Owner-system test file.
It intentionally triggers:
- Use-after-move.
- Duplicate mutable borrow with
mut ref. - Returning a reference to a local variable.
It also contains legal comparison functions for:
- Last-use move.
- Copy values.
- Immutable shared borrows.
Python tests
Added ownership-focused tests covering:
- Move consumes non-Copy values.
- Last-use move is allowed.
- Copy values remain usable after assignment.
- Duplicate mutable borrow is rejected.
- Returning local references is rejected.
File:
tests/test_ownership.py
Updated existing test strings for ref syntax:
tests/test_types.pytests/feat.py
Compatibility Notes
What v0.3.0 intentionally does not include
The Owner system is intentionally smaller than Rust’s ownership model.
Not included:
- Explicit lifetime annotations such as
<'a>. - Full non-lexical lifetime analysis.
- Pin/Unpin.
- Drop checking.
- Higher-ranked trait bounds.
- Full support for complex self-referential structures.
Current simplifications
- Temporary borrow scopes are statement-based.
- Function arguments are treated as read/borrowed by default for compatibility with existing Vix code.
- The Copy model is heuristic and may evolve as the type system gains explicit Copy/Move traits.
- References are still lowered through the existing pointer representation internally.
Validation
- Rebuilt
vixcsuccessfully with the newOwnership.cppcompilation unit. - Verified
src/test.vixemits the expected Owner errors. - Verified ownership diagnostics include real file names and columns.
- Verified
ref valuepermits shared immutable borrows. - Verified
mut ref valueenforces mutable borrow exclusivity. - Verified updated examples pass
--check:examples/quicksort.vixexamples/swap.vixexamples/pointer.vixexamples/pointer2.vixexamples/nullptr.vixexamples/list.vix
- Verified regression sources no longer fail with ownership-specific
moved/borrowdiagnostics after compatibility adjustments. - Full Python test execution was not run in this environment because
pytestis not installed.
v0.2.10
Full Changelog: v0.2.9...v0.2.10
Vix Language v0.2.10 Release Notes
Release Date: 2026-06-06
New Features
Multi-object file linking support
- The compiler now supports linking multiple object files directly without recompilation.
- Usage:
vixc file1.o file2.o file3.o -o output - This enables separate compilation workflows where individual modules are compiled to
.ofiles first, then linked together. - Added new
vix_link_multi()API in the linker module to handle multiple input files. - Files:
src/main.c,src/compiler/Linker/Linker.h,src/compiler/Linker/Linker.cpp
Bug Fixes
Enum type definition now accepts leading |
- The parser now accepts an optional leading
|before the first variant in type alias enum definitions. - This allows writing enums in a more consistent style:
type T = | Int | Float | String | Bool | Unit - Previously, the first variant had to omit the
|, which was inconsistent with subsequent variants. - File:
src/parser/parser.y
Linker: removed hardcoded CRT object paths
- Fixed the ELF linker path discovery to check file existence before adding CRT objects (
crt1.o,crti.o,crtbegin.o,crtend.o,crtn.o) to the linker arguments. - Eliminated a redundant second call to
probeSysPathsduring ELF linking; the sysroot is now probed once and reused. - This fixes link failures on systems where the CRT objects are located in non-standard directories or where some objects are absent.
- File:
src/compiler/Linker/Linker.cpp
Validation
- Rebuilt
vixcsuccessfully. - Verified enum definitions with leading
|on the first variant now parse correctly. - Tested multi-object linking with
vixc a.o b.o -o prog.
v0.2.9
Full Changelog: v0.2.8...v0.2.9
Vix Language v0.2.9 Release Notes
Release Date: 2026-05-31
Diagnostics
Array parameter value-semantics warnings
- Added compile-time warnings for array parameters that are passed by value and then modified inside a function.
- The compiler now warns when a copied array parameter is modified without returning the modified array, helping catch code that accidentally assumes reference semantics.
- The compiler now warns when an array parameter length is read before modifying the copied parameter, highlighting stale-length patterns such as returning the old length after
push. - The compiler now warns when an array parameter is never used.
- Files:
src/Typeck/Typeck.cpp,tests/test_types.py
Cleaner warning output
- Improved warning formatting so multiline diagnostic messages render separate
notelines instead of being flattened into one long line. - Warning headers now use a more readable
warning: ...plus--> file:line:columnlayout. - Warning summaries now report the total warning count as
Found N warnings. - Removed
helptext from warnings to avoid suggesting unsupported syntax or language features. - Files:
src/utils/error.c,include/compiler.h,src/main.c
Code Generation
Global dynamic array push now writes back reallocated pointers
- Fixed
array.push(...)on global dynamic arrays so the data pointer returned byreallocis stored back into the global variable. - Fixed pushed struct elements so arrays such as
[Point]allocate using the struct element size and store the struct value, not a pointer byte sequence. - This fixes programs that build a global array with repeated
pushcalls and then iterate it withfor. - Files:
src/compiler/Funcs.cpp
Bug Fixes
For-loop numeric type promotion
- Fixed a type mismatch error when using a
forloop with a range where the start and end are different numeric types (e.g.,0 .. bytes_readwhere0isI32andbytes_readisI64). - The compiler now allows implicit numeric promotion between integer and float types in range expressions.
- Modified
src/Typeck/Typeck.cppto usepromote_numericfor range bounds. - Modified
include/unify.hto allow numeric type compatibility in unification. - Files:
src/Typeck/Typeck.cpp,include/unify.h
Example
Given:
fn add_point(points: [Point], p: Point): i32 {
let id = points.length
points.push(p)
return id
}
vixc now reports that points is copied, its mutation is lost, and the earlier length read may be stale relative to the copied mutation.
Validation
- Rebuilt
vixcsuccessfully. - Verified
src/test.vixemits the new array-parameter warnings. - Verified
src/test.vixnow compiles successfully (only an unused variable warning remains). - Verified warning output no longer emits
helplines or#[warn(unused_variables)]text. - Verified
src/test2.vixnow prints the pushed globalPointvalues instead of producing no output. - Verified standalone fixtures for copied-array mutation and unused array parameter warnings.
- Python test execution could not be run in this environment because
pytestis not installed.