Back to Crystal

Changelog 1.19

doc/changelogs/v1.19.md

1.20.134.8 KB
Original Source

Changelog 1.19

1.19.1 (2026-01-20)

Bugfixes

stdlib

  • (concurrency) [regression] Fix kqueue timer duration calculation (#16581, thanks @skuznetsov)
  • (concurrency) [regression] time calculations in IOCP and Monitor thread (#16583, thanks @ysbaddaden)

Infrastructure

  • Changelog for 1.19.1 (#16590, thanks @ysbaddaden)

1.19.0 (2026-01-14)

Breaking changes

stdlib

  • (crypto) Require OpenSSL 1.1.1+ or LibreSSL 3+ (#16480, thanks @ysbaddaden)

Features

lang

  • (macros) [breaking] Add compiler flag values (#16310, thanks @straight-shoota)
  • (macros) Add yielding variant of StringLiteral#gsub (#16378, thanks @Blacksmoke16)
  • (macros) Support StringLiteral#split(RegexLiteral) (#16423, thanks @HertzDevil)
  • (macros) Add StringLiteral#match (#16464, thanks @HertzDevil)
  • (macros) Make all overloads of ArrayLiteral#[] return nil on out of bounds (#16453, thanks @HertzDevil)

stdlib

  • (collection) Add NamedTuple#reverse_merge (#16229, thanks @andrykonchin)
  • (collection) Pad Hash#inspect, Tuple#inspect before { from first element (#16245, thanks @andrykonchin)
  • (collection) Add Set#map! (#16271, thanks @andrykonchin)
  • (collection) Add Hash#transform_keys! (#16280, thanks @andrykonchin)
  • (collection) Enhance error message for Hash#[] when key is wrong type for default block (#16442, thanks @Blacksmoke16)
  • (concurrency) Add Sync::Mutex and Sync::RWLock (#16399, thanks @ysbaddaden)
  • (concurrency) Add Sync::ConditionVariable (#16440, thanks @ysbaddaden)
  • (concurrency) Import Sync::Exclusive and Sync::Shared (#16487, thanks @ysbaddaden)
  • (crypto) Add OpenSSL::SSL::Context::Server#on_server_name for SNI (#16452, #16525, thanks @carlhoerberg, @straight-shoota)
  • (networking) Loosen type restrictions in StaticFileHandler helper methods from File to IO (#16238, thanks @andrykonchin)
  • (networking) Add IPSocket#ipv6_only (#16347, thanks @stakach)
  • (networking) Expose flags hint for getaddrinfo (#16528, thanks @stakach)
  • (numeric) Add Int.from_digits as inverse of Int#digits (#16237, #16566, thanks @andrykonchin, @ysbaddaden)
  • (numeric) Add BigInt.from_digits (#16259, thanks @HertzDevil)
  • (numeric) Add Int#tdivmod (#16258, thanks @andrykonchin)
  • (runtime) Add Proc#[] as alias to #call (#16220, thanks @andrykonchin)
  • (runtime) Add #unshift, #pop and #pop? to Crystal::PointerLinkedList (#16287, thanks @ysbaddaden)
  • (runtime) Add Random.next_bool and .next_int (#16297, thanks @ysbaddaden)
  • (runtime) Add Random#split and #split_internal API for splittable PRNGs (#16342, #16495, thanks @ysbaddaden)
  • (runtime) Add Pointer#fill (#16338, thanks @straight-shoota)
  • (runtime) Add Crystal::PointerLinkedList#first? (#16400, thanks @ysbaddaden)
  • (runtime) Ensure single reader and writer to system fd on Unix (#16209, thanks @ysbaddaden)
  • (runtime) Protect Box.unbox from dereferencing null pointer (#16514, thanks @straight-shoota)
  • (runtime) Register execution context schedulers with the event loop (#16519, thanks @ysbaddaden)
  • (runtime) Add Fiber::ExecutionContext::Scheduler.current? (#16521, thanks @ysbaddaden)
  • (runtime) Move execution context event loop lock to each event loop (#16520, thanks @ysbaddaden)
  • (serialization) Support deserialization of YAML anchors of value types (#16186, thanks @HertzDevil)
  • (serialization) Add end locations to scalars and aliases in YAML::Nodes.parse (#16187, thanks @HertzDevil)
  • (serialization) Set JSON::SerializableError#attribute when appropriate (#16158, thanks @spuun)
  • (serialization) Support large JSON files (#16211, thanks @RX14)
  • (serialization) Add YAML::Nodes.parse_all (#16247, thanks @HertzDevil)
  • (specs) Rescale execution context in spec runner with CRYSTAL_WORKERS (#16444, #16471, thanks @straight-shoota, @ysbaddaden)
  • (system) Add Process.debugger_present? for Windows and Linux (#16248, thanks @HertzDevil)
  • (system) Implement execvpe_impl (#16322, #16344, thanks @straight-shoota)
  • (system) Add ::exit(Process::Status) (#16436, thanks @straight-shoota)
  • (system) Standardize system error codes for File::Error (#16024, thanks @straight-shoota)
  • (system) Add Path#relative? (#16473, thanks @Sija)
  • (text) PCRE2: use thread local for jit stack and match data (#16175, thanks @ysbaddaden)
  • (text) Support 0X, 0O, 0B prefixes in string to integer conversion (#16226, thanks @andrykonchin)
  • (text) Add String#each_line parameter remove_empty (#16232, thanks @andrykonchin)
  • (time) Add weeks parameter to Time::Span.new (#16208, thanks @Sija)
  • (time) Treat GMT as a legacy alias of UTC (#16292, thanks @straight-shoota)
  • (time) Add /etc/zoneinfo to zoneinfo lookup paths (#16463, thanks @straight-shoota)
  • (time) Add support for $TZDIR (#16466, thanks @straight-shoota)
  • (time) Add Time::Instant (#16490, thanks @straight-shoota)
  • (time) [breaking] Adjust monotonic clocks to include suspended time with precision (#16516, thanks @straight-shoota)

compiler

  • (codegen) Build compiler with -Dexecution_context (#16447, #16502, thanks @ysbaddaden, @straight-shoota)
  • (interpreter) Support ->LibX.fun_name in the interpreter (#16194, thanks @ysbaddaden)
  • (semantic) Add error message to CrystalPath::NotFoundError (#16365, thanks @willhbr)
  • (semantic) Retain original location for errors in included, extended hooks (#13261, thanks @Blacksmoke16)

tools

  • (docs-generator) Add optional sanitizer to docs generator (#14646, #16251, thanks @nobodywasishere, @straight-shoota)

Bugfixes

lang

  • (macros) Fix nested sigil delimiter parsing inside macros (#16266, thanks @HertzDevil)

stdlib

  • Fix OptionParser subcommand help to respect custom summary_indent (#16334, thanks @kojix2)
  • (collection) Fix Hash methods to retain compare_by_identity flag (#16356, thanks @andrykonchin)
  • (collection) Fix Hash methods and retaining default value (#16374, thanks @andrykonchin)
  • (files) Fix condition for no-op lock_write to work without sockets (#16304, thanks @straight-shoota)
  • (networking) Fix HTTP::Cookie parsing trailing semicolons (#16328, thanks @alexkutsan)
  • (networking) [breaking] Make #flush in WebSocket#stream a no-op to not send wrongly frames (#16539, thanks @spuun)
  • (runtime) [deprecation] Add thread safety to default random (#16174, #16568, thanks @ysbaddaden)
  • (runtime) default execution context is Parallel (#16367, thanks @ysbaddaden)
  • (runtime) Crystal::PointerLinkedList#each stops iterating when deleting head (#16401, thanks @ysbaddaden)
  • (runtime) closing system fd is thread unsafe (#16289, thanks @ysbaddaden)
  • (runtime) Crystal::System::Process#rwlock with Crystal < 1.7 (UNIX) (#16482, thanks @ysbaddaden)
  • (runtime) urandom initialization isn't thread safe + refactor (#16479, thanks @ysbaddaden)
  • (runtime) execution context queue stress tests failures (#16472, thanks @ysbaddaden)
  • (runtime) don't use Time.monotonic in Fiber::ExecutionContext::Monitor (#16500, thanks @ysbaddaden)
  • (runtime) thread safety of Exception::Callstack (#16504, thanks @ysbaddaden)
  • (runtime) actually clear memory using gc_none on unix (#16562, thanks @BlobCodes)
  • (serialization) memory leak in XML.parse and XML.parse_html methods (#16414, thanks @ysbaddaden)
  • (serialization) memory leak in XML::Document#finalize (#16418, thanks @toddsundsted)
  • (serialization) memory leak in XML::Node#content= (#16419, thanks @toddsundsted)
  • (serialization) Fix use after unlink in XML::Node (#16432, thanks @toddsundsted)
  • (specs) Resolve inconsistent use of #inspect in expect_raises (#16265, #16375, thanks @andrykonchin, @straight-shoota)
  • (system) Create argv before fork (#16286, #16321, thanks @straight-shoota)
  • (system) Pass envp to execvpe (#16340, thanks @straight-shoota)
  • (system) Move make_envp before fork (#16351, thanks @straight-shoota)
  • (system) Replace Dir.cd with a non-raising alternative in pre-exec (#16352, #16369, thanks @straight-shoota)
  • (system) Fix reset directory if Process.exec fails (#16383, thanks @straight-shoota)
  • (system) Fix reorder Process.lock_write outside of .block_signals (#16465, thanks @straight-shoota)
  • (system) Disable process cancellation during fork (#16446, thanks @straight-shoota)

compiler

  • (cli) chore: correct progress step count to 14 (#16269, thanks @miry)
  • (codegen) Fix System V ABI for arrays of packed structs with misaligned fields (#16314, thanks @HertzDevil)
  • (debugger) Fix debug info for closured variables (#16393, thanks @HertzDevil)
  • (interpreter) interpreter handles self in inlined method with arguments (#16307, thanks @cyangle)
  • (interpreter) interpreter typeof should return concrete type (#16379, thanks @cyangle)
  • (interpreter) Fix variable shadowing bug in interpreter (#16335, thanks @cyangle)
  • (interpreter) interpreter musn't reuse dead fiber stacks (#16518, thanks @ysbaddaden)
  • (parser) Fix internal error if multi-assign RHS has splats (#16182, thanks @HertzDevil)
  • (parser) Fix regex delimiter detection in syntax highlighter (#16394, thanks @HertzDevil)
  • (parser) Merge adjacent StringLiterals before yielding (#16427, thanks @Blacksmoke16)
  • (parser) Fix Call#end_location w/ named arguments off-by-one error (#16542, thanks @Sija)
  • (parser) Fix incorrect location for parenthesized union AST nodes (#16552, thanks @Sija)
  • (semantic) Fix instantiation of abstract generic structs in virtual type lookup (#16513, thanks @Blacksmoke16)
  • (semantic) Fix variables assigned inside && conditions with method calls incorrectly got Nil added to their type (#16512, thanks @Blacksmoke16)

tools

  • (docs-generator) Fix doc generation when nesting multiple :inherit: directives (#16443, thanks @Blacksmoke16)
  • (docs-generator) Fix some doc inconsistencies for macros (#16561, thanks @Blacksmoke16)
  • (formatter) Fix incorrect formatting of multi-line macro expression with comment as first line (#16429, thanks @Blacksmoke16)
  • (formatter) Add multi-line formatting support to Generic formatter visitor (#16430, thanks @Blacksmoke16)

Chores

lang

  • (macros) [deprecation] Deprecate single-letter macro fresh variables with indices (#16267, thanks @HertzDevil)
  • (macros) [deprecation] Deprecate macro fresh variables with constant names (#16293, thanks @HertzDevil)

stdlib

  • (macros) [deprecation] Deprecate StringLiteral#split(ASTNode) for non-separator arguments (#16439, thanks @HertzDevil)
  • (time) [deprecation] Deprecate Time#inspect(io, *, with_nanoseconds) (#16416, thanks @straight-shoota)
  • (time) [deprecation] Deprecate Time.monotonic (#16545, thanks @straight-shoota)

compiler

  • (cli) Error when trying to build aarch64 with LLVM 12 and below (#15018, thanks @straight-shoota)

other

  • Update copyright year (#16550, thanks @HertzDevil)
  • Remove redundant begin/end blocks (#16554, thanks @straight-shoota)

Performance

stdlib

  • Avoid calling times.map (#16422, thanks @HertzDevil)
  • (runtime) Skip initialization of Pointer.malloc with zero value (#16333, thanks @straight-shoota)
  • (runtime) Call Pointer.malloc(size, value) in Slice.new(size, value) (#16358, thanks @straight-shoota)

compiler

  • Group temporary variables by file name: splats (#16242, thanks @HertzDevil)
  • (codegen) [regression] Only define the type name table in the main LLVM module (#16260, thanks @HertzDevil)
  • (codegen) Allow closures to use atomic allocation (#16360, thanks @HertzDevil)

Refactor

stdlib

  • Refactor flag and value parsing into a separate method (#16300, thanks @straight-shoota)
  • (cli) Refactor OptionParser#parse (#16233, thanks @kojix2)
  • (cli) Simplify OptionParser#handle_flag with guard clauses (#16309, thanks @kojix2)
  • (files) Fix: don't flush twice in File#truncate (UNIX) (#16395, thanks @ysbaddaden)
  • (llvm) simplify target initialization and support more targets (#16437, thanks @ysbaddaden)
  • (log) Log::Metadata should put parent entries first on extend (like Hash#merge) (#16098, thanks @spuun)
  • (networking) Split HTTP::Headers#get(Key) into undocumented overload (#16283, thanks @straight-shoota)
  • (networking) Remove internal type OAuth::Params (#16319, thanks @AnandRaj2224)
  • (runtime) Refactor Crystal::DWARF::LineNumbers::Sequence (#16214, thanks @HertzDevil)
  • (runtime) Extract Crystal::EventLoop#shutdown from #close (#16288, #16366, thanks @ysbaddaden)
  • (runtime) Prefer Random::Secure.random_bytes (#16298, thanks @ysbaddaden)
  • (runtime) Set default random arg to nil instead of Random::DEFAULT (#16299, thanks @ysbaddaden)
  • (runtime) Drop EventLoop#after_fork_before_exec (#16332, thanks @straight-shoota)
  • (runtime) Cleanup node on Crystal::PointerLinkedList#delete (#16398, thanks @ysbaddaden)
  • (runtime) Add Fiber::Stack#size (#16420, thanks @ysbaddaden)
  • (runtime) Fix: new_thread spec helper must return isolated context (not thread) (#16421, thanks @ysbaddaden)
  • (runtime) Fix: always use getrandom on Linux and Android >= 28 (#16478, thanks @ysbaddaden)
  • (system) Extract Crystal::System::Env.each_pointer on Unix (#16200, thanks @straight-shoota)
  • (system) Refactor internal Crystal::System::Process#fork on UNIX (#16191, #16373, thanks @ysbaddaden, @straight-shoota)
  • (system) Use execvpe when available (#16294, #16311, thanks @straight-shoota)
  • (system) Add Env.make_envp (#16320, #16384, thanks @straight-shoota)
  • (system) Fix pre-exec for closed file descriptor (#16359, thanks @straight-shoota)
  • (system) Move prepare_args into system implementation internals (#16362, thanks @straight-shoota)
  • (system) Extract unix/spawn.cr as a separate file (#16388, thanks @straight-shoota)
  • (system) Extract internal Process.block_signals helper (#16402, thanks @straight-shoota)
  • (system) Rename target aarch64-android to aarch64-linux-android (#16409, thanks @straight-shoota)
  • (text) Simplify String#byte_slice(Int) and String#byte_slice?(Int) (#16235, thanks @andrykonchin)
  • (time) Use clock_gettime on darwin (#16492, thanks @straight-shoota)
  • (time) Add Crystal::System::Time.instant (#16506, thanks @straight-shoota)
  • (time) Replace Time.monotonic with Time.instant [follow-up #16490] (#16498, thanks @straight-shoota)
  • (time) remove extraneous method definition for Time::Span#sign (#16553, thanks @plambert)

Documentation

lang

  • (annotations) Fix @[Deprecated] doc comment (#16302, thanks @jgaskins)

stdlib

  • (collection) Clarify Set's enumeration order (#16274, thanks @HertzDevil)
  • (concurrency) Add docs for Sync namespace (#16565, thanks @ysbaddaden)
  • (crypto) Remove outdated performance hint in Bcrypt docs (#16536, thanks @BlobCodes)
  • (macros) Fix invalid runtime types in macro docs (#16534, thanks @BlobCodes)
  • (networking) Add type restrictions to OAuth::Consumer#get_authorize_uri (#16285, thanks @straight-shoota)
  • (numeric) Improve docs for Int to mention Int128 and UInt128 (#16529, thanks @HCLarsen)
  • (runtime) Use to_slice for presentation in Pointer doc examples (#16345, thanks @straight-shoota)
  • (system) Add type restrictions to process (#16065, thanks @Vici37)
  • (text) Document String#split(Regex)'s capture group behavior (#16207, thanks @HertzDevil)
  • (text) Add type restrictions to regex directory (#16066, thanks @Vici37)

Specs

lang

  • (macros) Enhance specs for flag? macro (#16336, thanks @straight-shoota)

stdlib

  • (collection) Add specs for Slice.new (#16424, thanks @straight-shoota)
  • (concurrency) Fix thread name expectation with parallel execution context (#16517, thanks @straight-shoota)
  • (crypto) Fix: remove 1 second sleep in openssl/ssl/server spec (#16454, thanks @ysbaddaden)
  • (files) Add specs for IO#read_bytes with converter (#16250, thanks @straight-shoota)
  • (networking) Fix TCP specs to accept EAI_NODATA instead of EAI_NONAME for unresolvable hostname (#16496, thanks @straight-shoota)
  • (system) Add specs for Process.run (#16306, #16325, thanks @straight-shoota)
  • (time) Update zoneinfo to TZDB version 2025c (#16501, thanks @straight-shoota)

compiler

  • (semantic) Drop assert_expand_second and assert_expand_third helpers (#16244, thanks @HertzDevil)

Infrastructure

  • Changelog for 1.19.0 (#16510, thanks @ysbaddaden)
  • Update previous Crystal release 1.18.1 (#16212, thanks @matiasgarciaisaia)
  • Fix shellcheck violations (#16221, thanks @straight-shoota)
  • Fix markdownlint violations (#16222, #16252, thanks @straight-shoota)
  • Merge release/1.18@1.18.2 into master (#16246, thanks @straight-shoota)
  • Enable ameba rule Lint/SpecFilename (#16223, thanks @straight-shoota)
  • Encourage +1 reactions on issues and PRs for prioritization (#16241, thanks @straight-shoota)
  • Update previous Crystal release 1.18.2 (#16249, thanks @straight-shoota)
  • Add devenv (#16263, thanks @straight-shoota)
  • Add ameba to git-hooks (#16276, #16295, thanks @straight-shoota)
  • Add devenv profile lint (#16291, thanks @straight-shoota)
  • Update distribution-scripts (#16301, thanks @straight-shoota)
  • Makefile: Extract variable COMPILER_FLAGS (#16349, #16372, thanks @straight-shoota)
  • Fix shell.nix on Linux (#16346, thanks @straight-shoota)
  • Build compiler with -Dpreview_mt (#16380, thanks @straight-shoota)
  • Update devenv.lock (#16386, thanks @github-actions)
  • Update devenv.lock (#16408, thanks @github-actions)
  • Drop committed .envrc (#16462, thanks @straight-shoota)
  • Add git-hook to ensure changing both Makefile and Makefile.win at the same time (#16503, thanks @straight-shoota)
  • Makefile: Use simply expanded variables to avoid costly duplicate evaluation (#16509, thanks @straight-shoota)
  • Fix scripts/update-shards.sh (#16524, thanks @straight-shoota)
  • Update distribution-scripts (#16530, thanks @straight-shoota)
  • Update shards 0.20.0 (#16523, thanks @straight-shoota)
  • Update typos 1.38.1 (#16219, thanks @straight-shoota)
  • Build snap arm64 target + drop publish_snap target (#16491, thanks @ysbaddaden)
  • (ci) Update darwin jobs in circleci to m4pro.medium resource class (#16389, thanks @straight-shoota)
  • (ci) Update xcode to 26.0.1 on circleci (#16201, thanks @straight-shoota)
  • (ci) Update korthout/backport-action action to v3.4.1 (#16215, thanks @renovate)
  • (ci) [security] Pin GitHub action uses to commit hash (#16253, thanks @straight-shoota)
  • (ci) Add lint workflow running pre-commit (#16275, #16296, thanks @straight-shoota)
  • (ci) Fix issues in GHA workflows (#16282, thanks @straight-shoota)
  • (ci) Update GH Actions (#16290, thanks @renovate)
  • (ci) Update crate-ci/typos action to v1.39.0 (#16326, thanks @renovate)
  • (ci) Refactor matrix configuration in Linux workflow (#16331, thanks @straight-shoota)
  • (ci) Reduce smoke tests to building only std_spec (#16337, thanks @straight-shoota)
  • (ci) Merge gnu and musl tests into a single matrix (#16341, thanks @straight-shoota)
  • (ci) Fix pull_request trigger for smoke workflow (#16343, thanks @straight-shoota)
  • (ci) Update GH Actions (#16385, thanks @renovate)
  • (ci) Add workflow update-devenv (#16387, thanks @straight-shoota)
  • (ci) Update GH Actions (#16434, thanks @renovate)
  • (ci) Update distribution-scripts (#16411, thanks @straight-shoota)
  • (ci) Run smoke tests on docker images (#16441, thanks @straight-shoota)
  • (ci) Update actions/checkout digest to 8e8c483 (#16474, thanks @renovate)
  • (ci) Remove test_dist_linux_on_docker job (#16410, thanks @straight-shoota)
  • (ci) Push docker images directly to registry (#16488, thanks @straight-shoota)
  • (ci) Enable multiarch docker builds (#16493, thanks @straight-shoota)
  • (ci) Run multi-threading test job with execution context (#16339, thanks @straight-shoota)
  • (ci) build linux aarch64 tarballs (#16330, thanks @ysbaddaden)