"No op" release to get Windows release out
When we moved from CirrusCI to GitHub Actions, we had some issues with the Windows releases that were do to tiny typos in the config that linting didn't catch.
This resulted in there being no 0.56.0 and 0.56.1 Windows releases. Because 0.56.1 was primarily to fix a Windows bug, we are doing a 0.56.2 release that should hopefully work for Windows as we think we have found all the tiny typos.
[0.56.2] - 2023-09-16
- "No op" release to get Windows release out
Fix "double socket close" issue with Windows version of TCPConnection
When fixing a number of "smaller" Windows TCP networking issues a couple years back, in addition to fixing those issues, we introduced a new bug. That bug lingered for two years. It lingered in large part because it would only become apparent in a low resource environment.
When we recently switched our Windows CI from CirrusCI to GitHub Actions, we went from a high-resource environment to a low-resource environment and started getting a ton of "random" Windows TCP test failures.
The problem that was fairly easy to recreate in a test environment would be fairly unlikely in most applications but existed nontheless. The scenario in our test environment was like this:
- Test 1 runs and completes but hasn't done test teardown yet
- Test 2 starts up
- Test 1 runs the "buggy" line of code and closes the socket it has been using with OS, but doesn't reset its own internal record of the file descriptor for the socket.
- Test 2 is gets a socket from the OS with the file descriptor for the socket just closed by Test 1
- Test 1 still has a "valid" file descriptor and as part of full shutdown, closes the socket associated with "its" file descriptor. When Test 1 does this, test 2's socket closes and the test fails to complete successfully.
The problem would appear "in the wild" if a Windows application was quickly closing and opening TCP sockets in a manner similiar to the Pony standard library TCP tests.
[0.56.1] - 2023-09-16
- Fix "double socket close" issue with Windows version of TCPConnection (PR #4437)
N.B. There is no Windows version of this release due to a build system failure. The only change that is relevant to Windows is the
pony_check fix that will be picked up in the next Windows release.
Update Pony musl Docker images to Alpine 3.18
We've updated our
ponylang/ponyc:x.y.z-alpine images to be based on Alpine 3.18. Previously, we were using Alpine 3.16 as the base.
Drop support for Alpine versions prior to 3.17
We've dropped support for Alpine versions prior to 3.17. The ponyc compiler that we supply will not work on earlier Alpine versions. If you need to use on 3.16 or earlier, you'll need to patch the compiler and build from source.
The change is relatively straightforward and can be reverse engineered from the pull request that dropped 3.16 support.
FreeBSD is no longer a supported platform
We no longer have access to hardware that we can test FreeBSD on as part of our regular Continous Integration and Release cycles. As such, we are removing FreeBSD as a supported platform. We will make best effort attempts to not break FreeBSD, however, it is likely to fall behind and need maintenance from interested community members.
Add macOS on Intel support
We've re-added macOS on Intel as a fully supported platform. Nightly and release builds will are available via
We plan on maintaining macOS on Intel support for as long as we are doing our builds on GitHub Actions and GitHub provides macOS Intel runners.
Drop macOS on Apple Silicon as a fully supported platform
We've dropped macOS on Apple Silicon as a fully supported platform.
At the moment, we don't have access to a CI environment with macOS on Apple Silicon. Until we have one, we can no longer maintain macOS as a fully supported platform.
We expect that we can start offering full macOS support on Apple Silicon in Q4 of 2023. This assumes that GitHub rolls out their delayed macOS on Apple Silicon hosted CI runners in Q4.
As of Pony 0.56.0, we are no longer providing prebuilt Apple Silicon builds of ponyc. You can still build from source. And, existing prebuilt release and nightly macOS binaries will remain available via
ponyup and Cloudsmith.
Our plan is to maintain
ponyup on Apple Silicon as we don't expect any breaking changes to
ponyc before GitHub offers Apple Silicon runners.
We will be doing our best to not break macOS on Apple Silicon during the transition. Hopefully, our macOS on Intel and Linux on aarch64 CI coverage will keep any accidental breakage from impacting on macOS on Apple Silicon. We can not guarantee that, so, community support in the form of PRs to keep macOS on Apple Silicon working are greatly appreciated.
Avoid hangs in async pony_check properties when using actions
Due to a logical flaw in the
pony_check package regarding how the
fail_action(...) calls, it was possible for lingering executions of previous runs to call into the
_PropertyRunner instance that was already handling another run, completing or failing some actions of the current run. This has resulted in occasional hangs in CI.
With this change the hangs could not be reproduces locally or in CI.
[0.56.0] - 2023-08-30
- Avoid hangs in async pony_check properties when using actions (PR #4405)
- Add macOS on Intel as fully supported platform (PR #4390)
stable from Docker images
Previously, we were including our very old and very deprecated dependency management tool
stable in our
ponyc Docker images. We've stopped.
Fix broken linking when using a sanitizer
The internal link command used when building a Pony program with a sanitizer in place wasn't correctly generated and linking the program would fail. This has been fixed.
Fix memory errors with some
--debug program builds
When we upgraded to LLVM 15, we accidentally changed the optimization level applied to
--debug builds. That change in optimization levels surfaced a rather complicated bug that we've been looking into. The end result? Some programs would crash with memory errors like segfaults or bad access.
We've updated to go back to the optimization setup we had with LLVM 14. We recommend updating your
ponyc installation as soon as possible.
Move heap ownership info from chunk to pagemap
An internal runtime change has been made around where/how heap chunk ownership information is stored in order to improve performance. The tradeoff is that this will now use a little more memory in order to realize the performance gains.
[0.55.1] - 2023-08-16
- Fix broken linking when using a sanitizer (PR #4393)
- Fix memory errors with some
--debugprogram builds (PR #4372)
Switch supported MacOS version to Ventura
We've switched our supported MacOS version from Monterey to Ventura.
"Supported" means that all ponyc changes are tested on Ventura rather than Monterey and our pre-built ponyc distribution is built on Ventura.
Fixed a possible resource leak with
with blocks would allow the usage of
_ as a variable in the
_ variable isn't usable within the block itself and
dispose wasn't called on the variable as it isn't valid to call any methods on the special
The lack of
dispose call on objects that might control resources could result in a resource leak.
We've addressed the issue by disallowing
_ as a variable name in
This is a breaking change, albeit one we don't expect to have any "real-world" impact.
Drop Ubuntu 18.04 support
Ubuntu 18.04 has reached its end of life date. We've dropped it as a supported platform. That means, we no longer test against it when doing CI and we no longer create prebuilt binaries for installation via
ponyup for Ubuntu 18.04.
We will maintain best effort to keep Ubuntu 18.04 continuing to work for anyone who wants to use it and builds
ponyc from source.
[0.55.0] - 2023-05-27
Updated to LLVM 15
The Pony compiler now uses LLVM 15, which includes some significant changes:
- LLVM Pointers can no longer track an element type.
- LLVM Optimization passes need to be run through the New Pass Manager.
Removed MergeRealloc optimization pass
This release removes an optimization pass whose goal was to "merge successive reallocations of the same variable in a single allocation", because it turned out that the pass was not safe, and there was no immediately viable path to make it safe.
Unfortunately this pass was too simplistic and lacked the kind of sophisticated analysis that would be required to detect when reallocation was necessary to preserve program semantics, such as in the case of keeping the left and right sides of an
String.chop properly isolated. In certain circumstances, this pass would elide the buffer reallocation that needs to happen for the "copy on extend" semantics of extending the left side after such a chop.
If anyone wishes to do the work of attempting to re-architect this pass in a way that accounts for maintaining isolation of related but distinct pointers, they are welcome to pick up the code from the most recent commit that had this pass and port it for compatibility with latest Pony and LLVM, then carry forward the new plan.
Fix bug in HeapToStack optimization pass
Our "HeapToStack" optimization pass that takes Pony heap allocations and converts them to stack allocations where possible contained a bug where it was incorrectly marking some function calls. This could possibly lead to other optimization passes to make incorrect assumptions about the code which in turn, could lead to incorrect programs being generated.
[0.54.1] - 2023-04-12
- Fix bug in HeapToStack optimization pass (PR #4341)
- LLVM 15 (PR #4327)
Enable building of libponyc-standalone on MacOS
We now ship a "standalone" version of libponyc for MacOS. libponyc-standalone allows applications to use Pony compiler functionality as a library. The standalone version contains "all dependencies" needed in a single library. On MacOS, sadly "all dependencies" means "all that can be statically linked", so unlike Linux, dynamically linking to C++ standard library is required on MacOS.
An example pony program linking against it would need to look like this:
use "lib:ponyc-standalone" if posix or osx use "lib:c++" if osx actor Main new create(env: Env) => None
Update DTrace probes interface documentation
Our DTrace probes needed some care. Over time, the documented interface and the interface itself had drifted. We've updated all probe interface definitions to match the current implementations.
Improve usability of some DTrace probes
A number of runtime DTrace probes were lacking information required to make them useful. The probes for:
- GC Collection Starting
- GC Collection Ending
- GC Object Receive Starting
- GC Object Receive Ending
- GC Object Send Starting
- GC Object Send Ending
- Heap Allocation
All lacked information about the actor in question. Instead they only contained information about the scheduler that was active at the time the operation took place. Without information about the actor doing a collection, allocating memory, etc the probes had little value.
Remove ambiguity from "not safe to write" compiler error message
Previously, when displaying the "not safe to write" error message, the information provided was incomplete in a way that lead to ambiguity. A "not safe to write" error involves two components, the left side type being assigned to and the right side type being assigned to the left side. We were only displaying the right side, not the left side type, thus making it somewhat difficult to know exactly what the error was.
As an example, when trying to write to a field in an iso class instance, we get:
Error: /Users/jairocaro-accinoviciana/issues-pony-4290/demo.pony:10:11: not safe to write right side to left side x.foo = foo ^ Info: /Users/jairocaro-accinoviciana/issues-pony-4290/demo.pony:9:14: right side type: Foo ref let foo: Foo ref = Foo ^
The updated error message is now in the format:
Error: /Users/jairocaro-accinoviciana/issues-pony-4290/demo.pony:10:11: not safe to write right side to left side x.foo = foo ^ Info: /Users/jairocaro-accinoviciana/issues-pony-4290/demo.pony:9:14: right side type: Foo ref let foo: Foo ref = Foo ^ /Users/jairocaro-accinoviciana/issues-pony-4290/demo.pony:10:5: left side type: X iso x.foo = foo ^
Stop building "x86-64-unknown-linux-gnu" packages
Previously we built a "generic gnu" ponyc package and made it available via Cloudsmith and ponyup. Unfortunately, there is no such thing as a "generic gnu" ponyc build that is universally usable. The ponyc package only worked if the library versions on your Glibc based Linux distribution matched those of our build environment.
We've stoped building the "generic gnu" aka "x86-64-unknown-linux-gnu" packages of ponyc as they had limited utility and a couple of different ways of creating a very bad user experience. Please see our Linux installation instructions for a list of Linux distributions we currently create ponyc packages for.
Enable building of libponyc-standalone on Windows
We now ship a "standalone" version of libponyc for Windows. libponyc-standalone allows applications to use Pony compiler functionality as a library. The standalone version contains "all dependencies" needed in a single library. This library doesn't contain C or C++ runtime libs, as those get linked into every Pony program during compilation on Windows.
An example pony program linking against it on Windows would need to look like this:
use "lib:ponyc-standalone" if posix or osx or windows use "lib:c++" if osx actor Main new create(env: Env) => None
json package from the standard library
We accepted an RFC to remove the
json package from the standard library.
Per the RFC, the motivation for removal was:
The json package is a regular source of difficult for Pony users. It is an ok API for some JSON handling needs and a poor API for other needs. The package
parses a String representation of some JSON into a mutable tree of objects.
This mutable tree is excellent for modifying the JSON, it is also an excellent representation for constructing a JSON document. However, it makes parsing a String into an shareable data structure that can be sent between actors very difficult.
The Pony ecosystem would be better served by not having an "official" JSON library that is part of the standard library. We would be better of by encouraging many different libraries that approach the problem differently. Sometimes, a purely functional approach like that taken by jay is called for. Other times, an approach that tightly controls memory usage and other performance oriented characteristics is better as seen in pony-jason.
Having the current
json package in the standard library given all its failings is a bad look. Better to have someone ask "what's the best way to handle JSON" then to blindly start using the existing package.
The existing package could be improved and it is best improved outside of the standard library and RFC process. The RFC process intentionally moves slowly. The
json package is at best "beta" level software and would be greatly enhanced by a process that allows for more rapid change and experimentation. Further, it isn't essential to the community that a JSON library be part of the standard library. There's no cross library communication mechanism that depends on the existence of a standard JSON handling interface.
The library version of the
json library is now available at https://github.com/ponylang/json.
Fix waiting on Windows to properly admit I/O events
Previously, on Windows, we were calling
WaitForSingleObject rather than
WaitForSingleObjectEx when putting scheduler threads to sleep. This could have caused Windows I/O events to be missed.
[0.54.0] - 2023-02-27
- Remove ambiguity from "not safe to write" compiler error message (PR #4299)
- Fix waiting on Windows to be sure I/O events can still come in. (PR #4325)
Introduction of empty Ranges
Previously, it was easy to accidentally create infinite
Ranges due to the implementation giving precedence to parameters
inc and the iterative relationship that the next value be
idx + inc where
idx starts equal to
min. Iteration stopped when
idx was equal to or passed
max. This resulted in infinite ranges when either 1) the
inc was 0, or any of
inc were NaN, +Inf or -Inf, or 2) if no progress could be made from
max due to the sign of
inc. Therefore, even a seemingly correct range such as
Range[ISize](-10, 10, -1) would be infinite -- producing values
-10, -11, -12, ... rather than moving between values
10, as might be expected. In order to avoid this possible error of seemingly correct ranges, we decided to introduce empty ranges which produce no values and reclassify much of what was previously infinite to instead be empty. There are now three mutually exclusive classifications for ranges: finite, infinite, and empty ranges. Finite ranges will produce some number of values before terminating, infinite ranges will never terminate, and empty ranges will immediately terminate due to having no values.
User Code Changes
We conducted a search of public Pony code and it appears that the vast majority of
Range usage should not require any changes. The most likely required change is any infinite
Range producing an infinite iterator of a single value; for this we recommend switching to use of
Iter[A].repeat_value(value) from the itertools package.
The only remaining infinite ranges are a positive and negative towards their respective infinities, so any code that previously relied on an infinite iterator will need to change. For example, any code that previously flipped the sign of the iterator or max parameter as a way to iterate in a given direction infinitely will need to change.
Previously, the code below would iterate infinitely.
// This code will no longer work let nan = F64(0) / F64(0) for i in Range[F64](nan) do // Previously infinite in the positive direction end
Will now need to be specified as follows.
let inf = F64.max_value() + F64.max_value() for i in Range[F64](0, inf) do // Infinite in the positive direction end
We can flip this relationship for a negative iterator.
let inf = F64.max_value() + F64.max_value() for i in Range[F64](0, -inf, -1) do // Infinite in the negative direction end
Fix infinite loop in compiler
The following program used to cause an infinite loop in the compiler:
type Message is (String, String, None) interface tag Manager be handle_message(msg: Message val) actor Main new create(env: Env) => Foo(env, recover tag this end) be handle_message(msg: Message val) => None actor Foo var manager: Manager new create(env: Env, manager': Manager) => manager = manager' let notifier = InputNotifier(this) env.input(consume notifier) be handle_data(data: String) => manager.handle_message(("","",None)) class InputNotifier is InputNotify let parent: Foo new iso create(parent': Foo) => parent = parent' fun ref apply(data': Array[U8 val] iso) => parent.handle_data("")
Fix compiler segfault caused by infinite recursion
The following program used to cause ponyc to segfault due to infinite recursion:
type Message is ((I64 | String), String, None) interface tag Manager be handle_message(msg: Message val) actor Main new create(env: Env) => Foo(env, recover tag this end) be handle_message(msg: Message val) => None actor Foo var manager: Manager new create(env: Env, manager': Manager) => manager = manager' let notifier = InputNotifier(this) env.input(consume notifier) be handle_data(data: String) => manager.handle_message(("","",None)) class InputNotifier is InputNotify let parent: Foo new iso create(parent': Foo) => parent = parent' fun ref apply(data': Array[U8 val] iso) => parent.handle_data("")
Fix runtime segfault
A segfault was introduced in "Fix segfault caused by unsafe garbage collection optimization".
tag objects were being incorrectly traced which could eventually result in a segfault.
If you are using Pony version 0.52.3 to 0.52.5, we recommend upgrading as soon as possible.
[0.53.0] - 2023-01-04
- Fix infinite loop in compiler (PR #4293)
- Fix compiler segfault caused by infinite recursion (PR #4292)
- Fix runtime segfault (PR #4294)
- Implement empty ranges RFC (PR #4280)
Fix compiler crash when attempting to mutate a val field
In Pony 0.52.4 we fixed an unsoundness bug that had been introduced over the summer. While fixing that bug, an error case was missed and as a result, a compiler crash was created where an error message should have been generated.
We've fixed the crash and it now displays a "left side is immutable" error message.
[0.52.5] - 2022-12-30
Fix crash when handling parameters with invalid types
Fixes a compiler assert when checking a parameter for autorecovery that has an invalid type.
Fix some infinite loops during typechecking
Some recursive constraints could cause the typechecker to go into
an infinite loop while trying to check subtyping. These infinite
loops have now been fixed. An example program that demonstrates
the issue is below:
primitive Foo[T: (Unsigned & UnsignedInteger[T])] fun boom() => iftype T <: U8 then None end actor Main new create(env: Env) => Foo[U8].boom()
The use of T: UnsignedInteger[T] is valid and expected, but wasn't
being handled correctly in this situation by the typechecker in this context.
Fix a major bug which allowed mutating fields of a val object
A bug was introduced in 0.51.2 which caused some checks to allow mutating fields of a val object due to changes to some operations on capabilities. This bug is fixed: immutability is now checked separately from other properties.
If you are using Pony 0.51.2 to 0.52.3, you should upgrade to the 0.52.4 release that contains this fix as soon as possible.