Skip to content
GitHub Repository Forum RSS-Newsfeed

Crystal 1.15.0 is released!

Johannes Müller

We are announcing a new Crystal release 1.15.0 with several new features and bug fixes.

Pre-built packages are available on GitHub Releases and our official distribution channels. See crystal-lang.org/install for installation instructions.

Stats

This release includes 161 changes since 1.14.1 by 25 contributors. We thank all the contributors for all the effort put into improving the language! ❤️

Changes

Below we list the most remarkable changes in the language, compiler and stdlib. For more details, visit the full changelog.

Breaking

Constants are allowed to start with non-ascii uppercase and titlecase letters. Previously, only ASCII uppercase letters were valid as first character for the name of a constant.

This change makes things right, but it could break code that was valid before: Identifiers starting with non-ascii uppercase or titlecase letters were previously considered variable names, but are now constant names. The following example compiles in 1.14 but errors in 1.15:

Á = 1
Á = 2 # Error: already initialized constant Á

Read more in #15148.

Thanks , @nanobowers

Lifetime EventLoop

As introduced in the blog post A new Event Loop for UNIX operating systems we have a new event loop driver implementing RFC #0009. It integrates directly with the system selectors on Unix systems, removing the dependency on libevent.

The new implementation is supported on Linux, macOS, FreeBSD and Android and automatically enabled on these systems and do not require any changes to user code. In case you notice any issues with the new implementation, it’s possible to fall back to the old driver with the compile time flag -Devloop=libevent. Read more about caveats in the blog post and availability in the RFC.

This effort is part of the ongoing project to improve multi-threading support with the help of 84codes. We’ve started to integrate multi-threaded execution contexts from ysbaddaden/execution_context into the standard library, implementing RFC 2. We expect this to become available in the next release.

Thanks @ysbaddaden

Stabilized platform support

In the process of testing the event loop implementations across platforms we updated specs and fixed some smaller issues with platform support on operating systems without automated continuous testing (OpenBSD, FreeBSD, Dragonfly BSD and NetBSD).

We also enabled indirect branch tracking on OpenBSD where this is required (#15122). On other systems it’s opt in via compiler flags:

  • -Dcf-protection=branch for x86_64
  • -Dcf-protection=return for x86_64
  • -Dcf-protection=full for x86_64
  • -Dbranch-protection=bti for aarch64

Thanks @ysbaddaden

Windows

Our Windows efforts made a big step forward with adding MinGW-W64 and MSYS2 as alternative compiler toolchains. This required a bit of work for the compiler tooling and to cleanly separate toolchain and OS portability. These targets enable cross-compilation for Windows binaries from Unix systems.

And with the implementation of context switch (#15155) we’re also making good progress for Windows on ARM.

This adds three new Tier 3 targets x86_64-windows-gnu, aarch64-windows-msvc, and aarch64-windows-gnu.

Thanks @HertzDevil

More portable Process::Status

The Process::Status type was originally based on Unix conventions and later expanded for more portable semantics. There were however still a couple small insufficiencies for portability which we have now addressed.

Thanks @straight-shoota

Standard library

Iterator(T).empty creates an iterator with no elements (#15039)

Thanks @spuun

A new method Enumerable#find_value returns the first truthy block result (#14893).

["", nil, "foo", "bar"].find_value(&.presence) # => "foo"

Thanks @jgaskins

Log messages do not emit when issued with a block and the block returns nil. This was incorrectly also the case even when an exception instance was passed to the emit method. This was fixed in #15253 and a message is now emitted when an exception is passed. We also added new overloads for passing an exception without giving a block (#15257).

require "log"

# This used to not emit an error:
Log.error(exception: Exception.new("Oh no!")) { nil }

# This is a new overload to make this use case simpler:
Log.error(exception: Exception.new("Oh no!"))

Thanks @lachlan

The new method HTTP::Cookie#expire allows expiring a cookie, which effectively instructs clients to delete it (#14819).

Thanks @a-alhusaini

Traditionally, the regex multiline option Regex::CompileOptions::MULTILINE combines the PCRE MULTILINE and DOTALL options. In some cases you might want to use multiline matching without DOTALL. This is now possible with Regex::CompileOptions::MULTILINE_ONLY (#14870).

Thanks @ralsina

Compiler

The compiler emits position dependent code for embedded targets (eabi) (#15174).

Thanks @RX14

Compiler tools

We enabled some pending formatter features which had been available as opt-in for a while (#14718). These are likely to cause changes in a lot of code bases, so we collected a bunch of them to activate in a single release. These changes are backwards-compatible with the formatter from 1.14.1.

The crystal unreachable tool has a new codecov formatter (#15059).

Thanks @Blacksmoke16

Dependency Updates

We updated the bindings for LibreSSL, enabling a bunch of new functions (#15177).

Thanks @straight-shoota

Shards 0.19.0

The bundled shards release was updated to 0.19.0.

This new shards release brings some small improvements, most notably it forwards ARGV unmodified to subcommands (#631), and supports Codeberg as a git resolver (#656).

Thanks @luislavena and @miry

Deprecations


Thanks

We have been able to do all of this thanks to the continued support of 84codes and every other sponsor. To maintain and increase the development pace, donations and sponsorships are essential. OpenCollective is available for that.

Reach out to crystal@manas.tech if you’d like to become a direct sponsor or find other ways to support Crystal. We thank you in advance!

Contribute