Appa v2.2.0 (Stable)
This update fixes a cluster of miscompiles in generics, operator dispatch and ARC lowering, every one of them found while porting a Span[T]-shaped library to Gata and scaffolding the self-hosting example, bringing the compiler to v2.2.0:
-
Fixed operator dispatch firing on pointer-typed values.
ClassNameOffollows pointer indirection, so any expression whose type wasSomeClass*was treated as eligible forSomeClass's own operator overloads. A generic union'sT*payload, pattern-bound inside a generic function and advanced withptr + n, compiled into a call to the pointee class's+operator instead of pointer arithmetic wheneverTwas instantiated with a class that declared one. The same confusion reachedascasts, prefix and postfix operators, unary operators, binary operators, compound assignment and indexed compound assignment. All nine sites now use a newDirectClassNameOf, which reads a class reference and refuses to look through a pointer, soAdder*is a pointer and onlyAdderis a class. -
Fixed a generic method's call to a generic free function silently dropping the callee's definition.
DrainGenericInstancesCoredrained the free-function queue to empty and then the method queue, in that order and once each. Resolving a queued generic method can enqueue a fresh free-function instantiation, and by then nothing was left to drain it, so a module method with its own type parameter that called a generic free function reachable through no other call site emitted the call and never the function. Both drains now sit inside an outer loop that runs until the two queues are empty together. -
Fixed a dead release being appended after a
returnthat already released. A function with several early-exitif { return ...; }branches, whose final branch also returned a freshly built managed value, had the block's frame released a second time after its own return statement. Unreachable in C terms, but it emitted a release of a temporary the return had already handed off.LowerBlocknow checks whether the statements it produced already end in areturn,breakorcontinuebefore releasing the frame. -
Fixed
voidbeing emitted as the type of a return temporary. The loweredreturndeclares a__rettemp to hold the value across the frame's releases, and typed it from the returned expression rather than from the function. An expression that carries no IR type of its own producedvoid __ret0 = ...;, which no C compiler accepts.Ownershipnow tracks the declared return type of the function being lowered and falls back to it, saving and restoring it around nested functions the way it already did for the throws state. -
Fixed a
throwsfunction whose body ends without areturnfalling off the end of a non-void C function. The lowering that wraps returns inOk(...)never supplied the implicit one, so the emitted function simply ran out of statements while declaring aResultreturn type.LowerFunctionnow appendsreturn Ok(...)to anythrowsbody that is empty or does not already end in a return. -
Fixed G093 firing on code that manages a union's reference count by hand. The
unsafeblock warning suppresses itself when the block namesretainorrelease, but it only recognised the two intrinsics by their C names. A union's generated per-typeretain/releasepair did not match, so hand-counting a union insideunsafestill drew "this builds a value inside an 'unsafe' block, where it is never released". The check now also recognises a single-argument call to a union's own retain or release. -
Added argc/argv plumbing to the generated hosted
main. It wasint main(void), which left an environment's_env_argc/_env_argvwith nothing to read. It is nowint main(int argc, char** argv)and stashes both into thegata_argc/gata_argvglobals the hosted environment declares, which is what makeslibgata's newArgsmodule work. -
Extended the C-reserved rename list with the names the Windows headers claim.
windows.h, which the hosted preamble includes on that platform, definesmin,max,near,far,IN,OUT,OPTIONAL,CONST,VOID,TRUE,FALSE,interface,ERROR,INVALID_HANDLE_VALUEand the calling-convention macros. A local, parameter or struct member named after any of them compiled everywhere except Windows. All of them now take the same trailing-underscore rename as the C keywords. -
Added
CompilerBugRegressionTests, covering the first three fixes above end to end. Each one compiles the emitted C with a real host compiler and asserts on the program's output, rather than settling for "appa accepted it".
Installation
For setting up Appa in your own machine, grab one of the following executables depending on the platform and run appa install:
- Windows:
appa-win.exe - Linux:
appa-linux - MacOS on ARM (Apple Silicon):
appa-amac - MacOS on Intel (Legacy x64):
appa-imac