---
title: Crystal 1.5.0 is released!
version: 1.5.0
summary:
thumbnail: +
author:
---

We are delivering a new release with several bugfixes and improvements. Below we list the most important or interesting changes, without mentioning several bugfixes and smaller enhancements. For more details, visit the [changelog](https://github.com/crystal-lang/crystal/releases/tag/1.5.0). Breaking changes are marked with ⚠️.

Pre-built packages are available on [GitHub Releases](https://github.com/crystal-lang/crystal/releases/tag/1.5.0) and our official distribution channels.
See [crystal-lang.org/install](https://crystal-lang.org/install/) for installation instructions.

## Stats

In this release we included [102 changes since the 1.4.1 release](https://github.com/crystal-lang/crystal/pulls?q=is%3Apr+milestone%3A1.5.0) by 23 contributors. We thank all the effort put into improving the language! ❤️

Below we list the most remarkable changes in the language and stdlib.

## ⚠️ Parameters of methods implementing an abstract `def` must match the names

In order to provide better documentation and robustness, it is possible to explicitly associate arguments with their names ([ref](https://crystal-lang.org/reference/1.5/syntax_and_semantics/default_and_named_arguments.html#named-arguments)):

```crystal
class Foo
  def foo(name : Int32) : Nil
    p name
  end
end

Foo.new.foo name: 42
```

As a consequence, it is sensible to consider that the name of an argument is part of its interface. Before 1.5.0, however, the compiler was not checking that the name of arguments matched between an implementation of an abstract method and its definition. That is, the following example compiled without error or warning:

```crystal
abstract class FooAbstract
  abstract def foo(number : Int32) : Nil
end

class Foo < FooAbstract
  def foo(name : Int32) : Nil
    p name
  end
end
```

Starting from 1.5.0 ([#11915](https://github.com/crystal-lang/crystal/pull/11915)) the example above will raise a warning:

```plaintext
 6 | def foo(name : Int32) : Nil
             ^---
Warning: positional parameter 'name' corresponds to parameter 'number' of the overridden method FooAbstract#foo(number : Int32), which has a different name and may affect named argument passing
```

## Method restrictions from instance variables

When an instance variable is assigned the value of an untyped method argument, then the argument is restricted to share the same type as the instance variable.

For instance, consider this code:

```crystal
class Foo
  @x : Int64

  def initialize(x)
    @x = x
  end
end
```

Up to 1.4.1, `x` in `initialize` is unrestricted. This had several issues:

 1. If the user passes an incorrect argument, like `Foo.new 'a'`, instead of marking the error in the argument `'a'`, it blames `x` for not having the right type.

 2. No autocast is performed, for instance, if we pass an `Int32` instead: `Foo.new 1` fails.

 3. The generated documentation doesn't provide a hint of the type of the parameter `x`.

From 1.5.0, in an assignment like `@x = x`, parameter `x` gets the type of `@x`, effectively solving the three issues above. Details can be read from [#12103](https://github.com/crystal-lang/crystal/pull/12103).

> Note: This new feature is expected to be backwards compatible. If for some reason it brings you a headache you can disable it passing `-Dno_restrictions_augmenter` in the build options. Let us know in the [issue tracker](https://github.com/crystal-lang/crystal/issues) about it.

## Annotations allowed on method arguments

It is now possible to add an annotation to a parameter of a method or macro. As illustration, imagine a linter that warns if a parameter is not used.

```crystal
def foo(x); end  # Warning: argument `x` is not used
```

Then, we could signal the linter to not warn us in a particular case. Assume the following annotation provided by the linter:

```crystal
annotation MaybeUnused; end
```

Applying it to the parameter removes the warning (in this particular fictitious linter):

```crystal
def foo(@[MaybeUnused] x); end  # OK
```

Details in [#12039](https://github.com/crystal-lang/crystal/issues/12039).

## Constant indexers for tuples

When using a constant to index a tuple or named tuple, the typechecker will correctly infer the precise type of the value accessed ([#12012](https://github.com/crystal-lang/crystal/pull/12012)).

```crystal
KEY = "s"
foo = {s: "String", n: 0}

# Before 1.5.0 this failed; it would assume the type of foo[key] to be (String | Int32)
puts foo[KEY].size
```

## Additions in File API

New method [`File#delete?`](https://crystal-lang.org/api/1.5.0/File.html#delete%3F%28path%3APath%7CString%29%3ABool-class-method) that, instead of raising, returns `false` if the file doesn't exist. Similarly, there's a new [`Dir#delete?`](https://crystal-lang.org/api/1.5.0/Dir.html#delete%3F%28path%3APath%7CString%29%3ABool-class-method). Details in [#11887](https://github.com/crystal-lang/crystal/pull/11887).

Additionally, several `File` methods now also operate on an instance: [`File#chmod`](https://crystal-lang.org/api/master/File.html#chmod%28permissions%3AInt%7CPermissions%29%3ANil-instance-method), [`File#chown`](https://crystal-lang.org/api/master/File.html#chown%28uid%3AInt%3D-1%2Cgid%3AInt%3D-1%29%3ANil-instance-method), [`File#utime`](https://crystal-lang.org/api/master/File.html#utime%28atime%3ATime%2Cmtime%3ATime%29%3ANil-instance-method), and [`File#touch`](https://crystal-lang.org/api/master/File.html#touch%28time%3ATime%3DTime.utc%29%3ANil-instance-method). Details in [#11886](https://github.com/crystal-lang/crystal/pull/11886).

## Strengthening the security of `File.tempfile`

As per [#12076](https://github.com/crystal-lang/crystal/pull/12076), the creation of temporary files don't allow null characters in the strings forming the name of the file.

## NO_COLOR compliance

The compiler and the interpreter supports the [NO_COLOR](https://no-color.org) [environment variable](https://crystal-lang.org/reference/1.5/using_the_compiler/index.html#environment-variables) to disable colored output on the terminal. This is enabled by setting any non-empty value to `NO_COLOR`. Details in [#11984](https://github.com/crystal-lang/crystal/pull/11984).

## A big step towards native Windows support

The concurrency runtime on Windows is now backed by a functioning event loop ([#12149](https://github.com/crystal-lang/crystal/pull/12149)).
This crossed an important check in the [road to native Windows support](https://github.com/crystal-lang/crystal/issues/5430). Additionally, we now have a Windows-compatible `Makefile`([#11773](https://github.com/crystal-lang/crystal/pull/11773)).

## Improvements in the interpreter

The interpreter is coming to shape! [A whole bunch of interpreter bugs](https://github.com/crystal-lang/crystal/pulls?q=is%3Apr+sort%3Aupdated-desc+milestone%3A1.5.0+label%3Atopic%3Acompiler%3Ainterpreter) got fixed.
While it won't be released in the binaries distributions yet, we will work towards incorporating it in the major platforms right after this release. Stay tuned!
You can build the compiler with interpreter support locally with `make interpreter=1`, see the [interpreter introduction post for more info](https://crystal-lang.org/2021/12/29/crystal-i.html).

> **THANKS:**
> We have been able to do all of this thanks to the continued support of [84codes](https://www.84codes.com/), [Nikola Motor Company](https://nikolamotor.com/) and every other [sponsor](/sponsors). To maintain and increase the development pace, donations and sponsorships are essential. [OpenCollective](https://opencollective.com/crystal-lang) is available for that.
>
> Reach out to [crystal@manas.tech](mailto:crystal@manas.tech) if you’d like to become a direct sponsor or find other ways to support Crystal. We thank you in advance!
