# Changelog 1.14

## [1.14.1] (2025-01-08)

[1.14.1]: https://github.com/crystal-lang/crystal/releases/1.14.1

### Bugfixes

#### tools

- _(formatter)_ Handle trailing comma with multiple parameters on the same line ([#15097], thanks @Blacksmoke16)

[#15097]: https://github.com/crystal-lang/crystal/pull/15097

### Infrastructure

- Changelog for 1.14.1 ([#15323], thanks @straight-shoota)
- _(ci)_ Update XCode 15.3.0 in circleci ([#15327], thanks @straight-shoota)

[#15323]: https://github.com/crystal-lang/crystal/pull/15323
[#15327]: https://github.com/crystal-lang/crystal/pull/15327

## [1.14.0] (2024-10-09)

[1.14.0]: https://github.com/crystal-lang/crystal/releases/1.14.0

### Features

#### lang

- Allow `^` in constant numeric expressions ([#14951], thanks @HertzDevil)

[#14951]: https://github.com/crystal-lang/crystal/pull/14951

#### stdlib

- Add support for Windows on aarch64 ([#14911], thanks @HertzDevil)
- _(collection)_ **[breaking]** Add support for negative start index in `Slice#[start, count]` ([#14778], thanks @ysbaddaden)
- _(collection)_ Add `Slice#same?` ([#14728], thanks @straight-shoota)
- _(concurrency)_ Add `WaitGroup.wait` and `WaitGroup#spawn` ([#14837], thanks @jgaskins)
- _(concurrency)_ Open non-blocking regular files as overlapped on Windows ([#14921], thanks @HertzDevil)
- _(concurrency)_ Support non-blocking `File#read` and `#write` on Windows ([#14940], thanks @HertzDevil)
- _(concurrency)_ Support non-blocking `File#read_at` on Windows ([#14958], thanks @HertzDevil)
- _(concurrency)_ Support non-blocking `Process.run` standard streams on Windows ([#14941], thanks @HertzDevil)
- _(concurrency)_ Support `IO::FileDescriptor#flock_*` on non-blocking files on Windows ([#14943], thanks @HertzDevil)
- _(concurrency)_ Emulate non-blocking `STDIN` console on Windows ([#14947], thanks @HertzDevil)
- _(concurrency)_ Async DNS resolution on Windows ([#14979], thanks @HertzDevil)
- _(crypto)_ Update `LibCrypto` bindings for LibreSSL 3.5+ ([#14872], thanks @straight-shoota)
- _(llvm)_ Expose LLVM instruction builder for `neg` and `fneg` ([#14774], thanks @JarnaChao09)
- _(llvm)_ **[experimental]** Add minimal LLVM OrcV2 bindings ([#14887], thanks @HertzDevil)
- _(llvm)_ Add `LLVM::Builder#finalize` ([#14892], thanks @JarnaChao09)
- _(llvm)_ Support LLVM 19.1 ([#14842], thanks @HertzDevil)
- _(macros)_ Add `Crystal::Macros::TypeNode#has_inner_pointers?` ([#14847], thanks @HertzDevil)
- _(macros)_ Add `HashLiteral#has_key?` and `NamedTupleLiteral#has_key?` ([#14890], thanks @kamil-gwozdz)
- _(numeric)_ Implement floating-point manipulation functions for `BigFloat` ([#11007], thanks @HertzDevil)
- _(runtime)_ Stop & start the world (undocumented API) ([#14729], thanks @ysbaddaden)
- _(runtime)_ Add `Pointer::Appender#to_slice` ([#14874], thanks @straight-shoota)
- _(serialization)_ Add `URI.from_json_object_key?` and `URI#to_json_object_key` ([#14834], thanks @nobodywasishere)
- _(serialization)_ Add `URI::Params::Serializable` ([#14684], thanks @Blacksmoke16)
- _(system)_ Enable full backtrace for exception in process spawn ([#14796], thanks @straight-shoota)
- _(system)_ Implement `System::User` on Windows ([#14933], thanks @HertzDevil)
- _(system)_ Implement `System::Group` on Windows ([#14945], thanks @HertzDevil)
- _(system)_ Add methods to `Crystal::EventLoop` ([#14977], thanks @ysbaddaden)
- _(text)_ Add `underscore_to_space` option to `String#titleize` ([#14822], thanks @Blacksmoke16)
- _(text)_ Support Unicode 16.0.0 ([#14997], thanks @HertzDevil)

[#14911]: https://github.com/crystal-lang/crystal/pull/14911
[#14778]: https://github.com/crystal-lang/crystal/pull/14778
[#14728]: https://github.com/crystal-lang/crystal/pull/14728
[#14837]: https://github.com/crystal-lang/crystal/pull/14837
[#14921]: https://github.com/crystal-lang/crystal/pull/14921
[#14940]: https://github.com/crystal-lang/crystal/pull/14940
[#14958]: https://github.com/crystal-lang/crystal/pull/14958
[#14941]: https://github.com/crystal-lang/crystal/pull/14941
[#14943]: https://github.com/crystal-lang/crystal/pull/14943
[#14947]: https://github.com/crystal-lang/crystal/pull/14947
[#14979]: https://github.com/crystal-lang/crystal/pull/14979
[#14872]: https://github.com/crystal-lang/crystal/pull/14872
[#14774]: https://github.com/crystal-lang/crystal/pull/14774
[#14887]: https://github.com/crystal-lang/crystal/pull/14887
[#14892]: https://github.com/crystal-lang/crystal/pull/14892
[#14842]: https://github.com/crystal-lang/crystal/pull/14842
[#14847]: https://github.com/crystal-lang/crystal/pull/14847
[#14890]: https://github.com/crystal-lang/crystal/pull/14890
[#11007]: https://github.com/crystal-lang/crystal/pull/11007
[#14729]: https://github.com/crystal-lang/crystal/pull/14729
[#14874]: https://github.com/crystal-lang/crystal/pull/14874
[#14834]: https://github.com/crystal-lang/crystal/pull/14834
[#14684]: https://github.com/crystal-lang/crystal/pull/14684
[#14796]: https://github.com/crystal-lang/crystal/pull/14796
[#14933]: https://github.com/crystal-lang/crystal/pull/14933
[#14945]: https://github.com/crystal-lang/crystal/pull/14945
[#14977]: https://github.com/crystal-lang/crystal/pull/14977
[#14822]: https://github.com/crystal-lang/crystal/pull/14822
[#14997]: https://github.com/crystal-lang/crystal/pull/14997

#### compiler

- _(cli)_ Adds initial support for external commands ([#14953], thanks @bcardiff)
- _(interpreter)_ Add `Crystal::Repl::Value#runtime_type` ([#14156], thanks @bcardiff)
- _(interpreter)_ Implement `Reference.pre_initialize` in the interpreter ([#14968], thanks @HertzDevil)
- _(interpreter)_ Enable the interpreter on Windows ([#14964], thanks @HertzDevil)

[#14953]: https://github.com/crystal-lang/crystal/pull/14953
[#14156]: https://github.com/crystal-lang/crystal/pull/14156
[#14968]: https://github.com/crystal-lang/crystal/pull/14968
[#14964]: https://github.com/crystal-lang/crystal/pull/14964

### Bugfixes

#### lang

- Fix `Slice.literal` for multiple calls with identical signature ([#15009], thanks @HertzDevil)
- _(macros)_ Add location info to some `MacroIf` nodes ([#14885], thanks @Blacksmoke16)

[#15009]: https://github.com/crystal-lang/crystal/pull/15009
[#14885]: https://github.com/crystal-lang/crystal/pull/14885

#### stdlib

- _(collection)_ Fix `Range#size` return type to `Int32` ([#14588], thanks @straight-shoota)
- _(concurrency)_ Update `DeallocationStack` for Windows context switch ([#15032], thanks @HertzDevil)
- _(concurrency)_ Fix race condition in `pthread_create` handle initialization ([#15043], thanks @HertzDevil)
- _(files)_ **[regression]** Fix `File#truncate` and `#lock` for Win32 append-mode files ([#14706], thanks @HertzDevil)
- _(files)_ **[breaking]** Avoid flush in finalizers for `Socket` and `IO::FileDescriptor` ([#14882], thanks @straight-shoota)
- _(files)_ Make `IO::Buffered#buffer_size=` idempotent ([#14855], thanks @jgaskins)
- _(macros)_ Implement `#sort_by` inside macros using `Enumerable#sort_by` ([#14895], thanks @HertzDevil)
- _(macros)_ Fix internal error when calling `#is_a?` on `External` nodes ([#14918], thanks @HertzDevil)
- _(networking)_ Use correct timeout for `Socket#connect` on Windows ([#14961], thanks @HertzDevil)
- _(numeric)_ Fix handle empty string in `String#to_f(whitespace: false)` ([#14902], thanks @Blacksmoke16)
- _(numeric)_ Fix exponent wrapping in `Math.frexp(BigFloat)` for very large values ([#14971], thanks @HertzDevil)
- _(numeric)_ Fix exponent overflow in `BigFloat#to_s` for very large values ([#14982], thanks @HertzDevil)
- _(numeric)_ Add missing `@[Link(dll:)]` annotation to MPIR ([#15003], thanks @HertzDevil)
- _(runtime)_ Add missing return type of `LibC.VirtualQuery` ([#15036], thanks @HertzDevil)
- _(runtime)_ Fix main stack top detection on musl-libc ([#15047], thanks @HertzDevil)
- _(serialization)_ **[breaking]** Remove `XML::Error.errors` ([#14936], thanks @straight-shoota)
- _(specs)_ **[regression]** Fix `Expectations::Be` for module type ([#14926], thanks @straight-shoota)
- _(system)_ Fix return type restriction for `ENV.fetch` ([#14919], thanks @straight-shoota)
- _(system)_ `#file_descriptor_close` should set `@closed` (UNIX) ([#14973], thanks @ysbaddaden)
- _(system)_ reinit event loop first after fork (UNIX) ([#14975], thanks @ysbaddaden)
- _(text)_ Fix avoid linking `libpcre` when unused ([#14891], thanks @kojix2)
- _(text)_ Add type restriction to `String#byte_index` `offset` parameter ([#14981], thanks @straight-shoota)

[#14588]: https://github.com/crystal-lang/crystal/pull/14588
[#15032]: https://github.com/crystal-lang/crystal/pull/15032
[#15043]: https://github.com/crystal-lang/crystal/pull/15043
[#14706]: https://github.com/crystal-lang/crystal/pull/14706
[#14882]: https://github.com/crystal-lang/crystal/pull/14882
[#14855]: https://github.com/crystal-lang/crystal/pull/14855
[#14895]: https://github.com/crystal-lang/crystal/pull/14895
[#14918]: https://github.com/crystal-lang/crystal/pull/14918
[#14961]: https://github.com/crystal-lang/crystal/pull/14961
[#14902]: https://github.com/crystal-lang/crystal/pull/14902
[#14971]: https://github.com/crystal-lang/crystal/pull/14971
[#14982]: https://github.com/crystal-lang/crystal/pull/14982
[#15003]: https://github.com/crystal-lang/crystal/pull/15003
[#15036]: https://github.com/crystal-lang/crystal/pull/15036
[#15047]: https://github.com/crystal-lang/crystal/pull/15047
[#14936]: https://github.com/crystal-lang/crystal/pull/14936
[#14926]: https://github.com/crystal-lang/crystal/pull/14926
[#14919]: https://github.com/crystal-lang/crystal/pull/14919
[#14973]: https://github.com/crystal-lang/crystal/pull/14973
[#14975]: https://github.com/crystal-lang/crystal/pull/14975
[#14891]: https://github.com/crystal-lang/crystal/pull/14891
[#14981]: https://github.com/crystal-lang/crystal/pull/14981

#### compiler

- _(cli)_ Add error handling for linker flag sub commands ([#14932], thanks @straight-shoota)
- _(codegen)_ Allow returning `Proc`s from top-level funs ([#14917], thanks @HertzDevil)
- _(codegen)_ Fix CRT static-dynamic linking conflict in specs with C sources ([#14970], thanks @HertzDevil)
- _(interpreter)_ Fix Linux `getrandom` failure in interpreted code ([#15035], thanks @HertzDevil)
- _(interpreter)_ Fix undefined behavior in interpreter mixed union upcast ([#15042], thanks @HertzDevil)
- _(semantic)_ Fix `TopLevelVisitor` adding existing `ClassDef` type to current scope ([#15067], thanks @straight-shoota)

[#14932]: https://github.com/crystal-lang/crystal/pull/14932
[#14917]: https://github.com/crystal-lang/crystal/pull/14917
[#14970]: https://github.com/crystal-lang/crystal/pull/14970
[#15035]: https://github.com/crystal-lang/crystal/pull/15035
[#15042]: https://github.com/crystal-lang/crystal/pull/15042
[#15067]: https://github.com/crystal-lang/crystal/pull/15067

#### tools

- _(dependencies)_ Fix `crystal tool dependencies` format flat ([#14927], thanks @straight-shoota)
- _(dependencies)_ Fix `crystal tool dependencies` filters for Windows paths ([#14928], thanks @straight-shoota)
- _(docs-generator)_ Fix doc comment above annotation with macro expansion ([#14849], thanks @Blacksmoke16)
- _(unreachable)_ Fix `crystal tool unreachable` & co visiting circular hierarchies ([#15065], thanks @straight-shoota)

[#14927]: https://github.com/crystal-lang/crystal/pull/14927
[#14928]: https://github.com/crystal-lang/crystal/pull/14928
[#14849]: https://github.com/crystal-lang/crystal/pull/14849
[#15065]: https://github.com/crystal-lang/crystal/pull/15065

### Chores

#### stdlib

- **[deprecation]** Use `Time::Span` in `Benchmark.ips` ([#14805], thanks @HertzDevil)
- **[deprecation]** Deprecate `::sleep(Number)` ([#14962], thanks @HertzDevil)
- _(runtime)_ **[deprecation]** Deprecate `Pointer.new(Int)` ([#14875], thanks @straight-shoota)

[#14805]: https://github.com/crystal-lang/crystal/pull/14805
[#14962]: https://github.com/crystal-lang/crystal/pull/14962
[#14875]: https://github.com/crystal-lang/crystal/pull/14875

#### compiler

- _(interpreter)_ Remove TODO in `Crystal::Loader` on Windows ([#14988], thanks @HertzDevil)
- _(interpreter:repl)_ Update REPLy version ([#14950], thanks @HertzDevil)

[#14988]: https://github.com/crystal-lang/crystal/pull/14988
[#14950]: https://github.com/crystal-lang/crystal/pull/14950

### Performance

#### stdlib

- _(collection)_ Always use unstable sort for simple types ([#14825], thanks @HertzDevil)
- _(collection)_ Optimize `Hash#transform_{keys,values}` ([#14502], thanks @jgaskins)
- _(numeric)_ Optimize arithmetic between `BigFloat` and integers ([#14944], thanks @HertzDevil)
- _(runtime)_ **[regression]** Cache `Exception::CallStack.empty` to avoid repeat `Array` allocation ([#15025], thanks @straight-shoota)

[#14825]: https://github.com/crystal-lang/crystal/pull/14825
[#14502]: https://github.com/crystal-lang/crystal/pull/14502
[#14944]: https://github.com/crystal-lang/crystal/pull/14944
[#15025]: https://github.com/crystal-lang/crystal/pull/15025

#### compiler

- Avoid unwinding the stack on hot path in method call lookups ([#15002], thanks @ggiraldez)
- _(codegen)_ Reduce calls to `Crystal::Type#remove_indirection` in module dispatch ([#14992], thanks @HertzDevil)
- _(codegen)_ Compiler: enable parallel codegen with MT ([#14748], thanks @ysbaddaden)

[#15002]: https://github.com/crystal-lang/crystal/pull/15002
[#14992]: https://github.com/crystal-lang/crystal/pull/14992
[#14748]: https://github.com/crystal-lang/crystal/pull/14748

### Refactor

#### stdlib

- _(concurrency)_ Extract `select` from `src/channel.cr` ([#14912], thanks @straight-shoota)
- _(concurrency)_ Make `Crystal::IOCP::OverlappedOperation` abstract ([#14987], thanks @HertzDevil)
- _(files)_ Move `#evented_read`, `#evented_write` into `Crystal::LibEvent::EventLoop` ([#14883], thanks @straight-shoota)
- _(networking)_ Simplify `Socket::Addrinfo.getaddrinfo(&)` ([#14956], thanks @HertzDevil)
- _(networking)_ Add `Crystal::System::Addrinfo` ([#14957], thanks @HertzDevil)
- _(runtime)_ Add `Exception::CallStack.empty` ([#15017], thanks @straight-shoota)
- _(system)_ Refactor cancellation of `IOCP::OverlappedOperation` ([#14754], thanks @straight-shoota)
- _(system)_ Include `Crystal::System::Group` instead of extending it ([#14930], thanks @HertzDevil)
- _(system)_ Include `Crystal::System::User` instead of extending it ([#14929], thanks @HertzDevil)
- _(system)_ Fix: `Crystal::SpinLock` doesn't need to be allocated on the HEAP ([#14972], thanks @ysbaddaden)
- _(system)_ Don't involve evloop after fork in `System::Process.spawn` (UNIX) ([#14974], thanks @ysbaddaden)
- _(system)_ Refactor `EventLoop` interface for sleeps & select timeouts ([#14980], thanks @ysbaddaden)

[#14912]: https://github.com/crystal-lang/crystal/pull/14912
[#14987]: https://github.com/crystal-lang/crystal/pull/14987
[#14883]: https://github.com/crystal-lang/crystal/pull/14883
[#14956]: https://github.com/crystal-lang/crystal/pull/14956
[#14957]: https://github.com/crystal-lang/crystal/pull/14957
[#15017]: https://github.com/crystal-lang/crystal/pull/15017
[#14754]: https://github.com/crystal-lang/crystal/pull/14754
[#14930]: https://github.com/crystal-lang/crystal/pull/14930
[#14929]: https://github.com/crystal-lang/crystal/pull/14929
[#14972]: https://github.com/crystal-lang/crystal/pull/14972
[#14974]: https://github.com/crystal-lang/crystal/pull/14974
[#14980]: https://github.com/crystal-lang/crystal/pull/14980

#### compiler

- _(codegen)_ Compiler: refactor codegen ([#14760], thanks @ysbaddaden)
- _(interpreter)_ Refactor interpreter stack code to avoid duplicate macro expansion ([#14876], thanks @straight-shoota)

[#14760]: https://github.com/crystal-lang/crystal/pull/14760
[#14876]: https://github.com/crystal-lang/crystal/pull/14876

### Documentation

#### stdlib

- _(collection)_ **[breaking]** Hide `Hash::Entry` from public API docs ([#14881], thanks @Blacksmoke16)
- _(collection)_ Fix typos in docs for `Set` and `Hash` ([#14889], thanks @philipp-classen)
- _(llvm)_ Add `@[Experimental]` to `LLVM::DIBuilder` ([#14854], thanks @HertzDevil)
- _(networking)_ Add documentation about synchronous DNS resolution ([#15027], thanks @straight-shoota)
- _(networking)_ Add `uri/json` to `docs_main` ([#15069], thanks @straight-shoota)
- _(runtime)_ Add docs about `Pointer`'s alignment requirement ([#14853], thanks @HertzDevil)
- _(runtime)_ Reword `Pointer#memcmp`'s documentation ([#14818], thanks @HertzDevil)
- _(runtime)_ Add documentation for `NoReturn` and `Void` ([#14817], thanks @nobodywasishere)

[#14881]: https://github.com/crystal-lang/crystal/pull/14881
[#14889]: https://github.com/crystal-lang/crystal/pull/14889
[#14854]: https://github.com/crystal-lang/crystal/pull/14854
[#15027]: https://github.com/crystal-lang/crystal/pull/15027
[#15069]: https://github.com/crystal-lang/crystal/pull/15069
[#14853]: https://github.com/crystal-lang/crystal/pull/14853
[#14818]: https://github.com/crystal-lang/crystal/pull/14818
[#14817]: https://github.com/crystal-lang/crystal/pull/14817

### Specs

#### stdlib

- Remove some uses of deprecated overloads in standard library specs ([#14963], thanks @HertzDevil)
- _(collection)_ Disable `Tuple#to_static_array` spec on AArch64 ([#14844], thanks @HertzDevil)
- _(serialization)_ Add JSON parsing UTF-8 spec ([#14823], thanks @Blacksmoke16)
- _(text)_ Add specs for `String#index`, `#rindex` search for `Char::REPLACEMENT` ([#14946], thanks @straight-shoota)

[#14963]: https://github.com/crystal-lang/crystal/pull/14963
[#14844]: https://github.com/crystal-lang/crystal/pull/14844
[#14823]: https://github.com/crystal-lang/crystal/pull/14823
[#14946]: https://github.com/crystal-lang/crystal/pull/14946

#### compiler

- _(codegen)_ Support return types in codegen specs ([#14888], thanks @HertzDevil)
- _(codegen)_ Fix codegen spec for `ProcPointer` of virtual type ([#14903], thanks @HertzDevil)
- _(codegen)_ Support LLVM OrcV2 codegen specs ([#14886], thanks @HertzDevil)
- _(codegen)_ Don't spawn subprocess if codegen spec uses flags but not the prelude ([#14904], thanks @HertzDevil)

[#14888]: https://github.com/crystal-lang/crystal/pull/14888
[#14903]: https://github.com/crystal-lang/crystal/pull/14903
[#14886]: https://github.com/crystal-lang/crystal/pull/14886
[#14904]: https://github.com/crystal-lang/crystal/pull/14904

### Infrastructure

- Changelog for 1.14.0 ([#14969], thanks @straight-shoota)
- Update previous Crystal release 1.13.1 ([#14810], thanks @straight-shoota)
- Refactor GitHub changelog generator print special infra ([#14795], thanks @straight-shoota)
- Update distribution-scripts ([#14877], thanks @straight-shoota)
- Update version in `shard.yml` ([#14909], thanks @straight-shoota)
- Merge `release/1.13`@1.13.2 ([#14924], thanks @straight-shoota)
- Update previous Crystal release 1.13.2 ([#14925], thanks @straight-shoota)
- Merge `release/1.13`@1.13.3 ([#15012], thanks @straight-shoota)
- Update previous Crystal release 1.13.3 ([#15016], thanks @straight-shoota)
- **[regression]** Fix `SOURCE_DATE_EPOCH` in `Makefile.win` ([#14922], thanks @HertzDevil)
- _(ci)_ Update actions/checkout action to v4 - autoclosed ([#14896], thanks @renovate)
- _(ci)_ Update LLVM 18 for `wasm32-test` ([#14821], thanks @straight-shoota)
- _(ci)_ Pin package repos for OpenSSL packages ([#14831], thanks @straight-shoota)
- _(ci)_ Upgrade XCode 15.4.0 ([#14794], thanks @straight-shoota)
- _(ci)_ Update GH Actions ([#14535], thanks @renovate)
- _(ci)_ Add test for OpenSSL 3.3 ([#14873], thanks @straight-shoota)
- _(ci)_ Update GitHub runner to `macos-14` ([#14833], thanks @straight-shoota)
- _(ci)_ Refactor SSL workflow with job matrix ([#14899], thanks @straight-shoota)
- _(ci)_ Drop the non-release Windows compiler artifact ([#15000], thanks @HertzDevil)
- _(ci)_ Fix compiler artifact name in WindowsCI ([#15021], thanks @straight-shoota)
- _(ci)_ Restrict CI runners from runs-on to 8GB ([#15030], thanks @straight-shoota)
- _(ci)_ Increase memory for stdlib CI runners from runs-on to 16GB ([#15044], thanks @straight-shoota)
- _(ci)_ Use Cygwin to build libiconv on Windows CI ([#14999], thanks @HertzDevil)
- _(ci)_ Use our own `libffi` repository on Windows CI ([#14998], thanks @HertzDevil)

[#14969]: https://github.com/crystal-lang/crystal/pull/14969
[#14810]: https://github.com/crystal-lang/crystal/pull/14810
[#14795]: https://github.com/crystal-lang/crystal/pull/14795
[#14877]: https://github.com/crystal-lang/crystal/pull/14877
[#14909]: https://github.com/crystal-lang/crystal/pull/14909
[#14924]: https://github.com/crystal-lang/crystal/pull/14924
[#14925]: https://github.com/crystal-lang/crystal/pull/14925
[#15012]: https://github.com/crystal-lang/crystal/pull/15012
[#15016]: https://github.com/crystal-lang/crystal/pull/15016
[#14922]: https://github.com/crystal-lang/crystal/pull/14922
[#14896]: https://github.com/crystal-lang/crystal/pull/14896
[#14821]: https://github.com/crystal-lang/crystal/pull/14821
[#14831]: https://github.com/crystal-lang/crystal/pull/14831
[#14794]: https://github.com/crystal-lang/crystal/pull/14794
[#14535]: https://github.com/crystal-lang/crystal/pull/14535
[#14873]: https://github.com/crystal-lang/crystal/pull/14873
[#14833]: https://github.com/crystal-lang/crystal/pull/14833
[#14899]: https://github.com/crystal-lang/crystal/pull/14899
[#15000]: https://github.com/crystal-lang/crystal/pull/15000
[#15021]: https://github.com/crystal-lang/crystal/pull/15021
[#15030]: https://github.com/crystal-lang/crystal/pull/15030
[#15044]: https://github.com/crystal-lang/crystal/pull/15044
[#14999]: https://github.com/crystal-lang/crystal/pull/14999
[#14998]: https://github.com/crystal-lang/crystal/pull/14998
