module Crystal

Overview

Here lies the logic of the representation of the MixedUnionType.

Which structure is used to represent them is defined in LLVMTyper#create_llvm_type.

The #union_type_and_value_pointer will allow to read the current value of the union. The #store*_in_union operations allow to write the value in a unions. The #{assign|downcast|upcast}_distinct_union_types operation matches the semantics described in ./casts.cr

Together these operations should encapsulate the binary representation of the MixedUnionType.

Other unions like ReferenceUnionType that have a more trivial representation are not handled here.

Defined in:

compiler/crystal/annotatable.cr
compiler/crystal/codegen/ast.cr
compiler/crystal/codegen/cache_dir.cr
compiler/crystal/codegen/codegen.cr
compiler/crystal/codegen/crystal_llvm_builder.cr
compiler/crystal/codegen/debug.cr
compiler/crystal/codegen/dump_type_info.cr
compiler/crystal/codegen/experimental.cr
compiler/crystal/codegen/link.cr
compiler/crystal/codegen/llvm_builder_helper.cr
compiler/crystal/codegen/llvm_id.cr
compiler/crystal/codegen/llvm_typer.cr
compiler/crystal/codegen/types.cr
compiler/crystal/codegen/unions.cr
compiler/crystal/compiler.cr
compiler/crystal/config.cr
compiler/crystal/crystal_path.cr
compiler/crystal/error.cr
compiler/crystal/exception.cr
compiler/crystal/ffi/lib_ffi.cr
compiler/crystal/interpreter/c.cr
compiler/crystal/macros/interpreter.cr
compiler/crystal/macros/methods.cr
compiler/crystal/macros/types.cr
compiler/crystal/program.cr
compiler/crystal/progress_tracker.cr
compiler/crystal/semantic/ast.cr
compiler/crystal/semantic/bindings.cr
compiler/crystal/semantic/class_vars_initializer_visitor.cr
compiler/crystal/semantic/cleanup_transformer.cr
compiler/crystal/semantic/cover.cr
compiler/crystal/semantic/exception.cr
compiler/crystal/semantic/filters.cr
compiler/crystal/semantic/hooks.cr
compiler/crystal/semantic/literal_expander.cr
compiler/crystal/semantic/main_visitor.cr
compiler/crystal/semantic/match.cr
compiler/crystal/semantic/method_lookup.cr
compiler/crystal/semantic/method_missing.cr
compiler/crystal/semantic/new.cr
compiler/crystal/semantic/normalizer.cr
compiler/crystal/semantic/path_lookup.cr
compiler/crystal/semantic/restrictions.cr
compiler/crystal/semantic/restrictions_augmenter.cr
compiler/crystal/semantic/suggestions.cr
compiler/crystal/semantic/to_s.cr
compiler/crystal/semantic/transformer.cr
compiler/crystal/semantic/type_guess_visitor.cr
compiler/crystal/semantic/type_intersect.cr
compiler/crystal/semantic/type_merge.cr
compiler/crystal/semantic/type_to_restriction.cr
compiler/crystal/semantic/warnings.cr
compiler/crystal/syntax/ast.cr
compiler/crystal/syntax/exception.cr
compiler/crystal/syntax/lexer.cr
compiler/crystal/syntax/parser.cr
compiler/crystal/syntax/to_s.cr
compiler/crystal/syntax/token.cr
compiler/crystal/syntax/transformer.cr
compiler/crystal/syntax/visitor.cr
compiler/crystal/tools/context.cr
compiler/crystal/tools/dependencies.cr
compiler/crystal/tools/expand.cr
compiler/crystal/tools/formatter.cr
compiler/crystal/tools/implementations.cr
compiler/crystal/tools/init.cr
compiler/crystal/tools/macro_code_coverage.cr
compiler/crystal/tools/playground/agent_instrumentor_transformer.cr
compiler/crystal/tools/print_hierarchy.cr
compiler/crystal/tools/print_types_visitor.cr
compiler/crystal/tools/table_print.cr
compiler/crystal/tools/unreachable.cr
compiler/crystal/types.cr
compiler/crystal/util.cr
compiler/crystal/warnings.cr
crystal/datum.cr
crystal/dwarf.cr
crystal/dwarf/abbrev.cr
crystal/dwarf/info.cr
crystal/dwarf/line_numbers.cr
crystal/dwarf/strings.cr
crystal/main.cr
crystal/once.cr
crystal/print_buffered.cr
crystal/small_deque.cr
crystal/tracing.cr

Constant Summary

BUILD_COMMIT = "2482c62c1"

The build commit identifier of the Crystal compiler.

BUILD_DATE = "2026-05-15"

The build date of the Crystal compiler.

CACHE_DIR = "/home/runner/.cache/crystal"

The cache directory configured for the Crystal compiler.

The value is defined by the environment variable CRYSTAL_CACHE_DIR and defaults to the user's configured cache directory.

DEFAULT_PATH = "$ORIGIN/../share/crystal/src"

The default Crystal path configured in the compiler. This value is baked into the compiler and usually points to the accompanying version of the standard library.

DESCRIPTION = "Crystal 1.20.2 [2482c62c1] (2026-05-15)\n\nLLVM: 20.1.8\nDefault target: x86_64-unknown-linux-gnu\n"

Full version information of the Crystal compiler. Equivalent to crystal --version.

GET_EXCEPTION_NAME = "__crystal_get_exception"
HOST_TRIPLE = "x86_64-unknown-linux-gnu"

The LLVM target triple of the host system (the machine that the compiler runs on).

LIBRARY_PATH = "/home/runner/work/_temp/crystal-latest-true-undefined/bin/../lib/crystal"

Colon-separated paths where the compiler searches for (binary) libraries.

The value is defined by the environment variables CRYSTAL_LIBRARY_PATH.

LLVM_VERSION = "20.1.8"

The version of LLVM used by the Crystal compiler.

MAIN_NAME = "__crystal_main"
MALLOC_ATOMIC_NAME = "__crystal_malloc_atomic64"
MALLOC_NAME = "__crystal_malloc64"
ONCE = "__crystal_once"
ONCE_INIT = "__crystal_once_init"
PATH = "./lib:/home/runner/work/crystal_compiler_explained/crystal_compiler_explained/crystal-master/src"

Colon-separated paths where the compiler searches for required source files.

The value is defined by the environment variable CRYSTAL_PATH and defaults to DEFAULT_PATH.

RAISE_CAST_FAILED_NAME = "__crystal_raise_cast_failed"
RAISE_NAME = "__crystal_raise"
RAISE_OVERFLOW_NAME = "__crystal_raise_overflow"
REALLOC_NAME = "__crystal_realloc64"
TARGET_TRIPLE = "x86_64-unknown-linux-gnu"

The LLVM target triple of the target system (the machine that the compiler builds for).

VERSION = "1.20.2"

The version of the Crystal compiler.

Class Method Summary

Class Method Detail

def self.format(source, filename = nil, report_warnings : IO | Nil = nil, flags : Array(String) | Nil = nil) #

[View source]
def self.main(&) #

Defines the main routine run by normal Crystal programs:

  • Initializes runtime requirements (GC, ...)
  • Invokes the given block
  • Handles unhandled exceptions
  • Invokes at_exit handlers
  • Flushes STDOUT and STDERR

This method can be invoked if you need to define a custom main (as in C main) function, doing all the above steps.

For example:

fun main(argc : Int32, argv : UInt8**) : Int32
  Crystal.main do
    elapsed = Time.measure do
      Crystal.main_user_code(argc, argv)
    end
    puts "Time to execute program: #{elapsed}"
  end
end

Note that the above is really just an example, almost the same can be accomplished with at_exit. But in some cases redefinition of C's main is needed.


[View source]
def self.main(argc : Int32, argv : Pointer(Pointer(UInt8))) #

Main method run by all Crystal programs at startup.

This setups up the GC, invokes your program, rescuing any handled exception, and then runs at_exit handlers.

This method is automatically invoked for you, so you don't need to invoke it.

However, if you need to define a special main C function, you can redefine main and invoke Crystal.main from it:

fun main(argc : Int32, argv : UInt8**) : Int32
  # some setup before Crystal main
  Crystal.main(argc, argv)
  # some cleanup logic after Crystal main
end

The Crystal.main can also be passed as a callback:

fun main(argc : Int32, argv : UInt8**) : Int32
  LibFoo.init_foo_and_invoke_main(argc, argv, ->Crystal.main(Int32, UInt8**))
end

Note that before Crystal.main is invoked the GC is not setup yet, so nothing that allocates memory in Crystal (like new for classes) can be used.


[View source]
def self.main_user_code(argc : Int32, argv : Pointer(Pointer(UInt8))) #

Executes the main user code. This normally is executed after initializing the GC and before executing at_exit handlers.

You should never invoke this method unless you need to redefine C's main function. See Crystal.main for more details.


[View source]
def self.normalize_path(path) #

[View source]
def self.print_buffered(message : String, *args, to io : IO, exception = nil, backtrace = nil) : Nil #

Prepares an error message, with an optional exception or backtrace, to an in-memory buffer, before writing to an IO, usually STDERR, in a single write operation.

Avoids intermingled messages caused by multiple threads writing to a STDIO in parallel. This may still happen, since writes may not be atomic when the overall size is larger than PIPE_BUF, buf it should at least write 512 bytes atomically.


[View source]
def self.print_error(msg, color, stderr = STDERR, leading_error = true) #

[View source]
def self.print_error_buffered(message : String, *args, exception = nil, backtrace = nil) : Nil #

Identical to #print_buffered but eventually calls System.print_error(bytes) to write to stderr without going through the event loop.


[View source]
def self.print_hierarchy(program, io, exp, format) #

[View source]
def self.print_types(node) #

[View source]
def self.relative_filename(filename) #

[View source]
def self.safe_mangling(program, name) #

[View source]
def self.temp_executable(basename) #

[View source]
def self.tempfile(basename) #

[View source]
def self.trace(section : Tracing::Section, operation : String, time : UInt64 | Nil = nil, **metadata, &) #

[View source]
def self.trace(section : Tracing::Section, operation : String, time : UInt64 | Nil = nil, **metadata) #

[View source]
def self.with_line_numbers(source : String | Array(String), highlight_line_number = nil, color = false, line_number_start = 1) #

[View source]