Skip to content

abstract class Crystal::Type
inherits Reference

Abstract base class of all types

Included modules

Crystal::Annotatable

Direct known subclasses

Crystal::GenericClassInstanceMetaclassType Crystal::GenericInstanceType Crystal::GenericModuleInstanceMetaclassType Crystal::LiteralType Crystal::NamedType Crystal::TypeParameter Crystal::TypeSplat Crystal::UnionType Crystal::VirtualMetaclassType Crystal::VirtualType

Constants

ONE_ARG = [Arg.new("a1")]

SuggestableDefName = /\A[a-z_]/

Class methods

.merge(nodes : Array(ASTNode))

View source

.merge(types : Array(Type))

View source

.merge!(type1 : Type, type2 : Type)

View source

.merge!(types_or_nodes)

View source

.new(program : Program)

View source

Methods

#abstract?

Returns true if this type is abstract.

View source

#abstract_leaf?

Returns true if this type is abstract and it has no concrete subclasses. This can happen if this type has abstract subclasses, or non-abstract generic subclasses without instantiations.

View source

#add_including_type(mod)

View source

#add_instance_var_initializer(name, value, meta_vars)

View source

#add_subclass(subclass)

View source

#all?

Yields self and returns true if the block returns a truthy value. UnionType overrides it and yields all types in turn and returns true if for each of them the block returns true.

View source

#all_class_vars

View source

#all_instance_vars

View source

#all_instance_vars_count

View source

#all_subclasses

Returns all subclasses of this type, including subclasses of subclasses recursively.

View source

#allowed_in_lib?

Returns true if this type can be used in a lib declaration: in a fun, struct/union member, or typedef.

View source

#allows_instance_vars?

Returns true if this type can have instance vars. Primitive types, and types like Reference and Object, can't have instance vars.

View source

#ancestors

View source

#append_cover(array)

View source

#append_to_expand_union_types(types)

View source

#bool_type?

View source

#can_be_stored?

Returns true if this type can be assigned to an instance or class variable, or used in a generic type argument.

As of now, abstract base type such as Object, Reference, Value, Int, and unbound generic types such as Array(T), can't be stored.

View source

#check_method_missing(signature, call)

View source

#check_restriction_exception

Checks whether an exception needs to be raised because of a restriction failure. Only overwritten by literal types (NumberLiteralType and SymbolLiteralType) when they produce an ambiguous call.

View source

#class?

View source

#class_var_owner

Returns the type that owns class vars for a type.

This method returns self, but subclasses might override. For example, a metaclass' class_var_owner is the instance type.

View source

#class_vars

View source

#common_ancestor(other)

View source

#compatible_with?(type)

View source

#cover

View source

#cover_size

View source

#declare_instance_var(name, type : Type, annotations = nil)

View source

#define_method_from_method_missing(method_missing, signature, original_call)

View source

#defs : Hash(String, Array(DefWithMetadata))?

Returns the methods defined in this type, indexed by their name. This does not include methods defined in ancestors.

View source

#depth

View source

#devirtualize

Returns the non-virtual type of a given type (returns self if self is already non-virtual)

View source

#doc : String?

Returns any doc comments associated to this type.

View source

#double_variadic?

View source

#each_cover

View source

#each_namespace(& : ModuleType -> ) : Nil

Yields each namespace this type belongs to, excluding the Program itself.

View source

#extern?

Returns true if this is an extern C struct or union (extern_union? tells which one)

View source

#extern_union?

Returns true if this is an extern C union (extern? will be true too)

View source

#filter_by(other_type)

View source

#filter_by_responds_to(name)

View source

#generic_nest

View source

#generic_type

View source

#get_instance_var_initializer(name)

View source

#has_def?(name)

View source

#has_def_without_parents?(name)

View source

#has_in_type_vars?(type)

View source

#has_inner_pointers?

Returns true if the type has inner pointers. This is useful to know because if a type doesn't have inner pointers we can use malloc_atomic instead of malloc in Pointer.malloc for a tiny performance boost.

This behaviour is documented in Pointer.malloc

View source

#has_instance_var_initializer?(name)

View source

#has_protected_access_to?(type, allow_same_namespace = true)

Determines if self can access type assuming it's a protected access. If allow_same_namespace is true (the default), protected also means the types are in the same namespace. Otherwise, it means they are just in the same type hierarchy.

View source

#implements?(other_type : Type)

View source

#implicitly_converted_in_c_to?(expected_type)

Returns true if this type can be implicitly converted to expected_type when this is a lib fun argument, without involving to_unsafe or numeric conversions. For example nil can be passed to an argument of type pointer.

View source

#includes_type?(type)

View source

#including_types

View source

#index_of_instance_var(name)

View source

#inspect(io : IO) : Nil

Appends a String representation of this object which includes its class name, its object address and the values of all instance variables.

class Person
  def initialize(@name : String, @age : Int32)
  end
end

Person.new("John", 32).inspect # => #<Person:0x10fd31f20 @name="John", @age=32>
View source

#instance_type

View source

#instance_vars

View source

#leaf?

Returns true if this type has no subclasses.

View source

#llvm_name(io)

View source

#llvm_name

View source

#locations : Array(Location)?

Returns all locations where this type is declared

View source

#lookup_class_var(name)

View source

#lookup_class_var?(name)

View source

#lookup_defs(name : String, all_defs : Array(Def), lookup_ancestors_for_new : Bool? = false)

View source

#lookup_defs(name : String, lookup_ancestors_for_new : Bool = false)

View source

#lookup_defs_with_modules(name)

View source

#lookup_defs_without_parents(name : String)

View source

#lookup_defs_without_parents(name : String, all_defs : Array(Def))

View source

#lookup_first_def(name, block)

View source

#lookup_instance_var(name)

View source

#lookup_instance_var?(name)

View source

#lookup_macro(name, args : Array, named_args)

Looks up a macro with the given name and matching the given args and named_args. Returns: - a Macro, if found - nil, if not found - DefInMacroLookup if not found and a Def was found instead

In the case of DefInMacroLookup, it means that macros shouldn't be looked up in implicit enclosing scopes such as Object or the Program.

View source

#lookup_macros(name)

Looks up macros with the given name. Returns: - an Array of Macro if found - nil if not found - DefInMacroLookup if not found and some Defs were found instead

View source

#lookup_matches(signature, owner = self, path_lookup = self, matches_array = nil, analyze_all = false)

View source

#lookup_matches_with_modules(signature, owner = self, path_lookup = self, matches_array = nil, analyze_all = false)

View source

#lookup_matches_without_parents(signature, owner = self, path_lookup = self, matches_array = nil, analyze_all = false)

View source

#lookup_method_missing

View source

#lookup_new_in_ancestors?

Should new be looked up in ancestors?

This is true if this type doesn't define any initialize methods.

View source

#lookup_path(names : Array(String), lookup_in_namespace = true, include_private = false, location = nil) : Type | ASTNode | Nil

Looks up a path (for example: Foo::Bar::Baz) relative to self.

For example, given:

class Foo
  class Bar
    class Baz
    end
  end
end

If self is Foo and we invoke lookup_path(["Bar", "Baz"]) on it, we'll get Foo::Bar::Baz as the return value.

The path is searched in the current type's ancestors, and optionally in its namespace, according to lookup_in_namespace.

Returns nil if the path can't be found.

include_private controls whether private types are found inside other types (when doing Foo::Bar, Bar won't be found if it's private).

location can be passed and is the location where the lookup happens, and is useful to find file-private types.

The result can be an ASTNode in the case the path denotes a type variable whose variable is an ASTNode. One such example is the N of StaticArray(T, N) for some instantiated StaticArray.

If the path is global (for example ::Foo::Bar), the search starts at the top level.

View source

#lookup_path(path : Path, lookup_in_namespace = true, include_private = false, location = path.location) : Type | ASTNode | Nil

Looks up a path (for example: Foo::Bar::Baz) relative to self.

For example, given:

class Foo
  class Bar
    class Baz
    end
  end
end

If self is Foo and we invoke lookup_path(["Bar", "Baz"]) on it, we'll get Foo::Bar::Baz as the return value.

The path is searched in the current type's ancestors, and optionally in its namespace, according to lookup_in_namespace.

Returns nil if the path can't be found.

include_private controls whether private types are found inside other types (when doing Foo::Bar, Bar won't be found if it's private).

location can be passed and is the location where the lookup happens, and is useful to find file-private types.

The result can be an ASTNode in the case the path denotes a type variable whose variable is an ASTNode. One such example is the N of StaticArray(T, N) for some instantiated StaticArray.

If the path is global (for example ::Foo::Bar), the search starts at the top level.

View source

#lookup_path_item(name : String, lookup_in_namespace, include_private, location) : Type | ASTNode | Nil

Looks up a single path item relative to *self`.

If lookup_in_namespace is true, if the type is not found in self or self's parents, the path item is searched in this type's namespace. This parameter is useful because when writing Foo::Bar::Baz, Foo should be searched in enclosing namespaces, but Bar and Baz not.

View source

#lookup_similar_def(name, args_size, block)

View source

#lookup_similar_def_name(name, args_size, block)

View source

#lookup_similar_instance_var_name(name)

View source

#lookup_similar_path(node : Path)

View source

#lookup_similar_path(names : Array(String), lookup_in_namespace = true)

View source

#lookup_type(node : ASTNode, self_type = self.instance_type, allow_typeof = true, free_vars : Hash(String, TypeVar)? = nil, find_root_generic_type_parameters = true) : Type

Searches the type that corresponds to the given node, relative to self.

This method handles AST nodes in the type grammar:

  • Path: Foo::Bar::Baz
  • Union: T | U
  • Metaclass: T.class
  • Generic: Foo(T)
  • ProcNotation: T -> U
  • TypeOf: typeof(...)
  • Self: self

Passing other AST nodes will raise an exception.

self_type is the type that will be used when self is encountered in the node.

If allow_typeof is false, this method raises if there's a typeof in the given node.

If free_vars is given, when resolving a Path, types will be first searched in the given Hash.

If find_root_generic_type_parameters is true (the default), type parameters relative to self_type will be found. If false, they won't be found.

For example, given:

class Foo
  class Bar(T)
  end

  class Baz
  end
end

If self is Foo and Bar(Baz) is given, the result will be Foo::Bar(Baz).

View source

#lookup_type?(node : ASTNode, self_type = self.instance_type, allow_typeof = true, free_vars : Hash(String, TypeVar)? = nil, find_root_generic_type_parameters = true) : Type?

Similar to lookup_type, but returns nil if a type can't be found.

View source

#lookup_type_var(node : Path, free_vars : Hash(String, TypeVar)? = nil, find_root_generic_type_parameters = true, remove_alias = true) : Type | ASTNode

Similar to lookup_type, but the result might also be an ASTNode, for example when looking N relative to a StaticArray.

View source

#lookup_type_var?(node : Path, free_vars : Hash(String, TypeVar)? = nil, raise = false, find_root_generic_type_parameters = true) : Type | ASTNode | Nil

Similar to lookup_type_var, but might return nil.

View source

#macros : Hash(String, Array(Macro))?

Returns all macros defines in this type, indexed by their name. This does not include methods defined in ancestors.

View source

#metaclass : Type

Returns this type's metaclass, which holds class methods for this type.

View source

#metaclass?

View source

#module?

View source

#namespace : ModuleType

The namespace this type belongs to. Every type belongs to a namespace, and, when not explicit, the namespace is the Program itself.

View source

#nil_type?

View source

#nilable?

View source

#no_return?

View source

#opaque_id

An opaque id of every type. 0 for Nil, non zero for others, so we can sort types by opaque_id and have Nil in the beginning.

View source

#packed?

Returns true if this type has the @[Packed] annotation on it (only applicable for C structs)

View source

#parents

View source

#passed_as_self?

Returns true if this type is passed as a self argument in the codegen phase. For example a method whose receiver is the Program, or a Metaclass, doesn't have a self argument.

View source

#passed_by_value?

Returns true if this type passed by value (if it's not a primitive type). In the codegen phase these types are passed as byval pointers.

View source

#pointer?

View source

#pretty_print(pp)

View source

#private=(set_private)

View source

#private?

View source

#proc?

View source

#program : Crystal::Program

Returns the program where this type belongs.

View source

#reference_like?

Returns true if this type inherits from Reference or if this is a union type where all types are reference types or nil. In this case this type can be represented with a single pointer.

View source

#remove_alias

View source

#remove_alias_if_simple

View source

#remove_indirection

View source

#remove_literal

View source

#remove_typedef

View source

#replace_type_parameters(instance) : Type

Replace type parameters in this type with the type parameters of the given instance type.

View source

#restrict(other : Underscore, context)

View source

#restrict(other : Arg, context)

View source

#restrict(other : NumberLiteral, context)

View source

#restrict(other : Splat, context)

View source

#restrict(other : ProcNotation, context)

View source

#restrict(other : ASTNode, context)

View source

#restrict(other : Metaclass, context)

View source

#restrict(other : Generic, context)

View source

#restrict(other : Path, context)

View source

#restrict(other : Union, context)

View source

#restrict(other : TypeOf, context)

View source

#restrict(other : Self, context)

View source

#restrict(other : Type, context)

View source

#restrict(other : GenericClassType, context)

View source

#restrict(other : VirtualType, context)

View source

#restrict(other : UnionType, context)

View source

#restrict(other : AliasType, context)

View source

#restrict(other : Nil, context)

View source

#restriction_of?(other : ASTNode, owner, strict = false)

View source

#restriction_of?(other : Type, owner, strict = false)

View source

#restriction_of?(other : AliasType, owner, strict = false)

View source

#restriction_of?(other : VirtualType, owner, strict = false)

View source

#restriction_of?(other : UnionType, owner, strict = false)

View source

#same_namespace?(other)

Returns true if self and other are in the same namespace.

View source

#sizeof_type

Returns the type that has to be used in sizeof and instance_sizeof computations

View source

#splat_index

View source

#struct?

Returns true if this type is a struct.

View source

#subclasses : Array(Type)

Returns direct subclasses of this type.

View source

#superclass : Type?

Returns this type's superclass, or nil if it doesn't have one

View source

#to_s(io : IO) : Nil

Appends a short String representation of this object which includes its class name and its object address.

class Person
  def initialize(@name : String, @age : Int32)
  end
end

Person.new("John", 32).to_s # => #<Person:0x10a199f20>
View source

#to_s(*, generic_args : Bool = true)

View source

abstract #to_s_with_options(io : IO, skip_union_parens : Bool = false, generic_args : Bool = true, codegen : Bool = false) : Nil

View source

#type_desc

View source

#type_var?(name)

Returns true if name if an unbound type variable in this (generic) type.

View source

#type_vars

View source

#types

View source

#types?

View source

#unbound?

View source

#virtual?

View source

#virtual_metaclass?

View source

#virtual_type

View source

#virtual_type!

View source

#void?

View source