Skip to content

Releases: ponylang/ponyc

0.43.0

14 Jul 19:53
Compare
Choose a tag to compare

Add prebuilt ponyc binaries for Rocky Linux 8

Prebuilt nightly versions of ponyc are now available from our Cloudsmith nightlies repo. Release versions will be available in the release repo starting with this release.

CentOS 8 releases were added as we currently support CentOS 8, but it will be discontinued in a few months and Rocky Linux provides a seamless transition path.

If you are a Pony user and are looking for prebuilt releases for your distribution, open an issue and let us know. We'll do our best to add support for any Linux distribution version that is still supported by their creators.

Fix OOM error when running ponyc built with xcode 12.5

Changes in Big Sur and xcode as of 12.5 have lead to an out of memory error with ponyc. If pony's allocator is built with usage of VM_FLAGS_SUPERPAGE_SIZE_ANY on, it will run out of memory if xcode 12.5 was used to build.

VM_FLAGS_SUPERPAGE_SIZE_ANY isn't required on earlier versions. It does however, improve performance when allocating. Usage of VM_FLAGS_SUPERPAGE_SIZE_ANY has been removed as it also doesn't work on newer M1 based machines and thus, is on its way out in general.

Fix API mismatch errors when linking pony programs on MacOS

We have been setting a minimal API version for ponyc that didn't match the LLVM value. This resulted in errors about how the link versions didn't match. The warnings caused no issues running programs, but did lead to confusion amongst new users. They were also annoying to look at all the time.

We did some testing and determined that there's no need to set the value as we can build ponyc and other pony programs on Big Sur and still use on earlier versions of MacOS.

There might be some issues that crop up in the future, but as far as we can tell, for normal ponyc MacOS usage, we dont need to set macosx-version-min.

Fix broken IsPrime standard library feature

Any prime after 1321 wasn't being correctly identified.

Prevent non-opaque structs from being used as behaviour parameters

When a non-opaque object is sent across actors, its type descriptor is used by the garbage collector in order to trace it. Since structs lack a type descriptor, using a val or iso struct as a parameter behaviour could lead to a runtime segfault. This also applies to tuple parameters where at least one element is a non-opaque struct.

This is a breaking change. Existing code will need to wrap struct parameters in classes or structs, or use structs with a tag capability. Where you previously had code like:

struct Foo

actor Main
  new create(env: Env) =>
    inspect(recover Foo end)

  be inspect(f: Foo iso) =>
    // Do something with f

you will now need

struct Foo

class Bar
  let f: Foo = Foo

actor Main
  new create(env: Env) =>
    inspect(recover Bar end)

  be inspect(wrap: Bar iso) =>
    // Do something with wrap.f

When using tuples with struct elements, you don't need to wrap the entire tuple. It is enough to wrap the struct elements.

Update to LLVM 12.0.1

We've updated the LLVM used to build pony to LLVM 12.0.1 and in the process, we've dropped support for 32-bit ARM as supported platform.

We might bring 32-bit Arm back as a supported platform if the Arm fixes we need to do to get ponyc working on M1 also fix the current issues we have with 32-bit Arm with LLVM 12. The errors currently present the same so we assume that adding M1 support will bring 32-bit ARM along with it. If fixing the M1 issues doesn't fix 32-bit Arm issues then we'll have to make a decision about whether we bring back 32-bit Arm support.

[0.43.0] - 2021-07-14

Fixed

  • Fix OOM on MacOS when using xcode 12.5 (PR #3793)
  • Fix MacOS version mismatch warnings when linking Pony programs (PR #3798)
  • Fix the calculation of "is prime" for numbers after 1321. (PR #3799)
  • Prevent non-opaque structs from being used as behaviour parameters (PR #3781)

Added

  • Add support for prebuilt Rocky Linux versions (PR #3783)

Changed

0.42.0

07 Jul 13:34
Compare
Choose a tag to compare

Fix bug where Flags.remove could set flags in addition to unsetting them

Flags.remove when given a flag to remove that wasn't currently present in the set, would turn the flag on.
It should only be turning flags off, not turning them on.

Allow Flags instances to be created with a set bit encoding

Extending Flags.create to (optionally) allow initialization of a Flags
object with the numeric representation populated. This value defaults
to 0 (no flags set).

Don't allow PONYPATH to override standard library

Prior to this change, a library could contain a package called builtin that would override to standard library version. This could be an attack vector. You can still override the standard library location by using the ponyc --paths option.

Any code which relied on the PONYPATH items being before the standard library in the package search path will need to switch to using --paths on the ponyc command line.

[0.42.0] - 2021-07-07

Fixed

  • Fix bug where Flags.remove could set flags in addition to unsetting them (PR #3777)

Added

  • Allow Flags instances to be created with a set bit encoding (PR #3778)

Changed

  • Don't allow PONYPATH to override standard library (PR #3780)

0.41.2

29 Jun 18:25
Compare
Choose a tag to compare

Fix "iftype" expressions not being usable in lambdas or object literals

This release fixes an issue where the compiler would hit an assertion error when compiling programs that placed iftype expressions inside lambdas or object literals.

Fix code generation for variadic FFI functions on arm64

This release fixes an issue with code generation of variadic functions on arm64 architectures. The arm64 calling convention specifies that the named arguments of a variadic function (those arguments that are not optional) must be placed on registers, or on the stack if there are no available registers. Anonymous arguments (those that are optional) must always be placed on the stack. The Pony compiler would treat all variadic functions as if all their arguments were anonymous, thus placing every argument on the stack, even if there were available registers. This would cause issues on the C side of a variadic function, as programs would try and read from registers first, potentially finding uninitialized values.

[0.41.2] - 2021-06-29

Fixed

  • Fix "iftype" expressions not being usable in lambdas or object literals (PR #3763)
  • Fix code generation for variadic FFI functions on arm64 (PR #3768)

0.41.1

22 May 11:38
Compare
Choose a tag to compare

Fix type constraint check against NullablePointer being omitted in FFI declarations

This release fixes an issue where the compiler would not perform some type checks against FFI declarations. Specifically, the compiler would fail to validate that the type parameter to the NullablePointer type had to be a struct type. This check is important since a program that used a non-struct type in a NullablePointer could theoretically segfault at runtime.

[0.41.1] - 2021-05-22

Fixed

  • Fix NullablePointer type constraint check being omitted in FFI declarations (PR #3758)

0.41.0

07 May 12:47
Compare
Choose a tag to compare

Fix unsound checks for return subtyping

Changed the subtyping model used in the compiler,
fixing some unsound cases that were allowed for function returns.
This also will result in changed error messages, with more
instances of unaliasing instead of aliasing. The tutorial has
been updated with these changes.

This is a breaking change, as some code which used to be accepted
by the typechecker is now rejected. This could include sound code
which was not technically type-safe, as well as unsound code.

This code used to be erroneously allowed and is now rejected
(it would allow a val and an iso to alias):

class Foo
  let x: Bar iso = Bar
  fun get_bad(): Bar val =>
    x

In addition, the standard library Map class now has a weaker
type signature as it could not implement its current type signature.
The upsert and insert_if_absent methods now return T! instead of T

Improve error messages when matching on struct types

A struct type doesn't have a type descriptor, which means that they cannot be used in match or "as" statements. Before this change, the compiler would incorrectly warn that matching against a struct wasn't possible due to a violation of capabilities, which was confusing. With this release, the compiler will now show a more helpful error message, explicitly mentioning that struct types can't be used in union types.

As an example, the following piece of Pony code:

struct Rect

actor Main
  new create(env: Env) =>
    let a: (Rect | None) = None
    match a
    | let a': Rect => None
    | None => None
    end

would fail to compile on ponyc 0.40.0 with the following error message:

Error:
main.pony:7:7: this capture violates capabilities, because the match would need to differentiate by capability at runtime instead of matching on type alone
    | let a': Rect => None
      ^
    Info:
    main.pony:5:18: the match type allows for more than one possibility with the same type as pattern type, but different capabilities. match type: (Rect ref | None val)
        let a: (Rect | None) = None
                     ^
    main.pony:7:7: pattern type: Rect ref
        | let a': Rect => None
          ^
    main.pony:7:15: matching (Rect ref | None val) with Rect ref could violate capabilities
        | let a': Rect => None
                  ^

Starting with this release, the error message is:

Error:
main.pony:7:7: this capture cannot match, since the type Rect ref is a struct and lacks a type descriptor
    | let a': Rect => None
      ^
    Info:
    main.pony:5:18: a struct cannot be part of a union type. match type: (Rect ref | None val)
        let a: (Rect | None) = None
                     ^
    main.pony:7:7: pattern type: Rect ref
        | let a': Rect => None
          ^
    main.pony:7:15: matching (Rect ref | None val) with Rect ref is not possible, since a struct lacks a type descriptor
        | let a': Rect => None
                  ^

Make FFI declarations mandatory (RFC 68)

This release introduces a breaking change for code that uses the C-FFI (Foreign Function Interface). It is now mandatory to declare all FFI functions via use statements. In addition, it is now a syntax error to specify the return type of an FFI function at the call site. The tutorial has been updated with these changes.

Where you previously had code like:

let ptr = @pony_alloc[Pointer[U8]](@pony_ctx[Pointer[None]](), USize(8))
Array[U8].from_cpointer(ptr, USize(8))

you now need

// At the beginning of the file
use @pony_ctx[Pointer[None]]()
use @pony_alloc[Pointer[U8]](ctx: Pointer[None], size: USize)
// ...
let ptr = @pony_alloc(@pony_ctx(), USize(8))
Array[U8].from_cpointer(ptr, USize(8))

If you're calling a C function with a variable number of arguments (like printf), use ... at the end of the declaration:

use @printf[I32](fmt: Pointer[U8] tag, ...)
// ...
@printf("One argument\n".cpointer())
@printf("Two arguments: %u\n".cpointer(), U32(10))
@printf("Three arguments: %u and %s\n".cpointer(), U32(10), "string".cpointer())

FFI declarations are visible to an entire package, so you don't need to add type signatures to all Pony files.

Change the return type of String.add to String iso^ (RFC 69)

This release introduces a breaking change by changing the return type of String.add from String val to String iso^.

Where you previously had code like:

let c = Circle
let str = "Radius: " + c.get_radius().string() + "\n"
env.out.print(str)

you now need:

let c = Circle
let str = recover val "Radius: " + c.get_radius().string() + "\n" end
env.out.print(str)

or you can also let the compiler do the work for you by using explicit type declarations:

let c = Circle
let str: String = "Radius: " + c.get_radius().string() + "\n"
env.out.print(str)

The above code works since val is the default reference capability of the String type.

The new type makes it simpler to implement the Stringable interface by using String.add. Where before you had code like:

class MyClass is Stringable
  let var1: String = "hello"
  let var2: String = " world"

  fun string(): String iso^ =>
    recover
      String.create(var1.size() + var1.size())
        .>append(var1)
        .>append(var2)
    end

you can now implement the string method as such:

class MyClass is Stringable
  let var1: String = "hello"
  let var2: String = " world"

  fun string(): String iso^ =>
    var1 + var2

Improve error message when attempting to destructure non-tuple types

Sometimes, the compiler will infer that the return type of an expression is an union or an intersection of multiple types. If the user tries to destructure such result into a tuple, the compiler will emit an error, but it won't show the user what the inferred type is. This could be confusing to users, as they wouldn't know what went wrong with the code, unless they added explicit type annotations to the assigned variables.

Starting with this release, the compiler will now show what the inferred type is, so that the user can spot the problem without needing to explicitly annotate their code.

As an example, the following piece of Pony code:

actor Main
  new create(env: Env) =>
    (let str, let size) =
      if true then
        let str' = String(5) .> append("hello")
        (str', USize(5))
      else
        ("world", USize(5))
      end

would fail to compile on previous releases with the following error message:

Error:
main.pony:3:25: can't destructure a union using assignment, use pattern matching instead
    (let str, let size) =
                        ^

Starting with this release, the error message will show the inferred type of the expression:

Error:
main.pony:3:25: can't destructure a union using assignment, use pattern matching instead
    (let str, let size) =
                        ^
    Info:
    main.pony:4:7: inferred type of expression: ((String ref, USize val^) | (String val, USize val^))
          if true then
          ^

Fix memory corruption of chopped Arrays and Strings

With the introduction of chop on Array and String a few years ago, a constraint for the memory allocator was violated. This resulted in an optimization in the realloc code of the allocator no longer being safe.

Prior to this fix, the following code would print cats and sog. After the fix, it doesn't corrupt memory and correctly prints cats and dog.

actor Main
  new create(env: Env) =>
    let catdog = "catdog".clone().iso_array()
    (let cat, let dog) = (consume catdog).chop(3)
    cat.push('s')
    env.out.print(consume cat)
    env.out.print(consume dog)

[0.41.0] - 2021-05-07

Fixed

  • Change to Steed's model of subtyping (PR #3643)
  • Fix memory corruption with Array.chop and String.chop (PR #3755)

Changed

  • Improve error message for match on structs (PR #3746)
  • RFC 68: Mandatory FFI declarations (PR #3739)
  • Change return type of String.add to String iso^ (PR #3752)
  • Improve error message on destructuring of non-tuple types (PR #3753)

0.40.0

01 May 00:18
Compare
Choose a tag to compare

Add IsPrime to math package

Quickly determine if a given number is prime using the 6k ± 1 method.

All integers (excluding 2 and 3), can be expressed as (6k + i), where i = -1, 0, 1, 2, 3, or 4. Since 2 divides (6k + 0), (6k + 2), and (6k + 4), while 3 divides (6k + 3) that leaves only (6k - 1) and (6k + 1) for expressing primes

Fix possible memory leak

A possible memory leak in the process package was fixed.

Update supported FreeBSD to FreeBSD 13.0

As of this release, we now do all FreeBSD testing on FreeBSD 13.0 and all ponyc prebuilt packages are built on FreeBSD 13.0. We will make a best effort to not break prior versions of FreeBSD while they are "supported".

[0.40.0] - 2021-05-01

Fixed

  • Use built-in offset argument to cpointer (PR #3741)

Added

  • Add IsPrime checker to math package (PR #3738)

Changed

  • Change supported FreeBSD to 13.0 (PR #3743)

0.39.1

29 Mar 17:45
Compare
Choose a tag to compare

Fix compiler crash related to type parameter references

Previously, if a method signature in a trait or interface referenced a type
parameter before the type parameter itself was defined, the compiler would
crash. This is now fixed.

Fix early pipe shutdown with Windows' ProcessMonitor

Due to incorrect handling of a Windows pipe return value, the ProcessMonitor would sometimes shut down its pipe connections to external processes before it should have.

Fix literal inference with partial functions

Before this change, code such as 1~add(2) would hit an assertion error when the compiler tried to infer the type of the literal 2. The compiler tries to find the type of the receiver of the function (in this case 1), but before it lacked the ability to do so when using partial functions. In those cases, the compiler would try to look at the type of the ~ token, which is not a valid value literal, and as such it would fail.

[0.39.1] - 2021-03-29

Fixed

  • Fix compiler crash related to type parameter references (PR #3725)
  • Fix early pipe shutdown with Windows ProcessMonitor (PR #3726)
  • Fix literal inference through partial function (PR #3729)

0.39.0

27 Feb 16:53
Compare
Choose a tag to compare

Fix calculating the number of CPU cores on FreeBSD/DragonFly

The number of CPU cores is used by Pony to limit the number of scheduler threads (--ponymaxthreads) and also used as the default number of scheduler threads.

Previously, sysctl hw.ncpu was incorrectly used to determine the number of CPU cores on FreeBSD and DragonFly. On both systems sysctl hw.ncpu reports the number of logical CPUs (hyperthreads) and NOT the number of physical CPU cores.

This has been fixed to use kern.smp.cores on FreeBSD and hw.cpu_topology_core_ids * hw.cpu_topology_phys_ids on DragonFly to correctly determine the number of physical CPU cores.

This change only affects FreeBSD and DragonFly systems with hardware that support hyperthreading. For instance, on a 4-core system with 2-way HT, previously 8 scheduler threads would be used by default. After this change, the number of scheduler threads on the same system is limited to 4 (one per CPU core).

Change supported FreeBSD version to 12.2

We only maintain support for a single version of FreeBSD at a time due to limited usage of Pony of FreeBSD. We've switched from testing and building releases for 12.1 to 12.2, We would have done this sooner, but we hadn't noticed that 12.2 had been released.

Fix FFI declarations ignoring partial annotation

Previously, the compiler would ignore any ? annotations on FFI declarations, which could result in the generated code lacking any guards for errors, causing the final program to abort at runtime. This change fixes the problem by ensuring that the compiler checks if FFI declarations specify a partial annotation.

Fix building ponyc on DragonFly BSD

DragonFly BSD is lightly used as a ponyc platform. It is also "unsupported" due to lack of CI. Over time, ponyc fell out of being able to be built on DragonFly.

As of this release, you should be able to use ponyc on DragonFly again. However, do to the unsupported nature of the DragonFly port, it might break again in which case, updates from anyone using Pony on DragonFly will be needed.

Create a standalone libponyc on Linux

It's possible to use libponyc from projects other than ponyc. Using the library gives you access to all the various compiler functionality. However, it is hard to use the library because, you need to link in the correct libstdc++, libblake, and LLVM. Figuring out what is the correct version of each is very difficult.

With this change, a new library libponyc-standalone.a will be created as part of the build process.

Applications like the "in pony documentation generator" that we are working on will be able to link to libponyc-standalone and pick up all it's required dependencies.

Windows, BSD, and macOS libraries are not created at this time but can be added as needed in the future.

Fix symbol table patching for default implementations that replaces another method

This release fixes a compiler crash that could happen when a default implementation replaced another method with the same signature. An example of this is when intersecting two interfaces that both have a method with the same signature and the second interface provides a default implementation:

interface A
  fun f(): U32

interface B
  fun f(): U32 =>
    let x: U32 = 42
    x

interface C is (A & B)

In this case, the default implementation was copied to C, but without its symbol table, subsequently resulting in a compiler crash.

Fix tuple related compiler segfaults

Andreas Stührk indentified and fixed the source of two different open issues with tuple handling that caused the pony compiler to crash.

[0.39.0] - 2021-02-27

Fixed

  • Fix calculation of # CPU cores (FreeBSD/DragonFly) (PR #3707)
  • Fix partial FFI declarations ignoring partial annotation (PR #3713)
  • Fix building ponyc on DragonFly BSD (PR #3676)
  • Fix symbol table patching for overriding default methods (PR #3719)
  • Fix tuple related compiler segfaults (PR #3723)

Added

  • Create a standalone libponyc on Linux (PR #3716)

Changed

  • Update supported FreeBSD to 12.2 (PR #3706)

0.38.3

29 Jan 13:33
Compare
Choose a tag to compare

Fix memory safety problem with Array.from_cpointer

Previously, the from_cpointer method in arrays would trust the user to pass a valid pointer. This created an issue where the user could pass a null pointer using Pointer.create, leading to a situation where memory safety could be violated by trying to access an element of the array. This change makes it safe to pass a null pointer to from_cpointer, which will create a zero-length array.

Fix bad package names in generated documentation

Previously when you used ponyc's documentation generation functions on a code base that used relative imports like use "../foo", the package name in the generated documentation would be incorrect.

[0.38.3] - 2021-01-29

Fixed

  • Fix memory safety problem with Array.from_cpointer (PR #3675)
  • Fix bad package names in generated documentation (PR #3700)

0.38.2

26 Dec 13:54
Compare
Choose a tag to compare

Fix race conditions that can lead to a segfault

The 0.38.0 release introduced improvement to handling of short-lived actors. However, in the process it also introduced some race condition situations that could lead to segfaults. 0.38.1 introduced a fix that we hoped would address the problems, however, after that release we realized that it didn't fully address the situation. With this change, we've reworked the implementation of the short-lived actor improvements to avoid the trigger for the known race conditions entirely.

Fix compiler crash when an if block ends with an assignment that has no result value

This release fixes a compiler crash that used to occur when certain kinds of assignment expressions that have no logical result value were used as the last expression in an if block, and possibly other control flow constructs as well. Now the compiler makes sure that the code generation for those cases always bears a value, even though the type system guarantees that the value will never be used in such a case. This prevents generating invalid LLVM IR blocks that have no proper terminator instruction.

Fix link errors on macOS Big Sur

With the change from Catalina to Big Sur, Apple moved the location of the System library, which broke the linking phase of the compiler. This change fixes the problem by specifying the absolute path of the System library.

Fix unhandled null pointer that can lead to a segfault

Previously, the os_socket_listen and os_socket_connect internal functions would assume that calls to os_addrinfo_intern would never fail. The os_addrinfo_intern function returns a null pointer on failure, which could result in the callers attempting to free an invalid pointer, and causing a segfault. This change adds error handling on the socket functions, which fixes the problem.

[0.38.2] - 2020-12-26

Fixed

  • Fix race conditions that can lead to a segfault (PR #3667)
  • Fix compiler crash when an if block ends with an assignment that has no result value. (PR #3670)
  • Fix link errors on macOS Big Sur (PR #3686)
  • Fix unhandled null pointer returning from os_addrinfo_intern (PR #3687)