Crystal 1.15.0 is released!
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.
Process::Status#exit_status
is deprecated (#8647) to avoid confusion with#exit_code
. Its replacement#system_exit_status
(#15296) returns the platform-specific exit status.#exit_reason
and#exit_code
are better alternatives for portable code, though.- Fixed
Process::Status#exit_code
to raise when the status is abnormal instead of returning an incorrect success code (#15241).#exit_code?
is a non-raising alternative (#15247). - We aligned
Process::Status#signal_exit?
to now considerSignal::STOP
(0x7e
) a signal, in concordance with#exit_signal
(#15289) and added#exit_signal?
(#15284) as a non-raising variant of the latter. Process::Status#to_s
now prints unknown signals correctly (#15280). On Windows, it prints the name of known status constants (#15283) and formats large values in hexadecimal (#15285).Process::Status#normal_exit?
was redefined on Windows to align withExitReason::Normal
(#15255, #15267) and#abnormal_exit?
is a shortcut for the inverse (#15266).
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
Process::Status#exit_status
: Use#exit_reason
,#exit_code
, or#system_exit_status
instead (#8647) (more details in More portableProcess::Status
).
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